问题
Here is my Go program.
package main
import (
"fmt"
)
type Person struct {
Name string
}
func main() {
p := &Person{"Jack"}
// The following statement makes sense. We dereference the
// pointer to reach the Person object and then retrieve its Name
// field.
fmt.Println((*p).Name)
// But the following statement does not make sense. How does
// this code work by retrieving the Name field directly from the
// pointer without dereferencing it?
fmt.Println(p.Name)
}
Here is the output.
$ go run foo.go
Jack
Jack
When p
is of type *Person
, i.e. a pointer to Person
, how is it legal to access its field Name
without dereferencing it? I see all Go tutorials using the syntax p.Name
instead of (*p).Name
but where exactly the Go language defines p.Person
as a legal syntax?
回答1:
Spec: Selectors:
The following rules apply to selectors:
[...] if the type of
x
is a named pointer type and(*x).f
is a valid selector expression denoting a field (but not a method),x.f
is shorthand for(*x).f
.
The language spec helps you with the pointer syntax to make it feel you're not even using pointers in some cases. Dereferencing a pointer to access its field is one of them. Also you can call methods that have pointer receiver on non-pointer values if they are addressable, see Calling a method with a pointer receiver by an object instead of a pointer to it?
Also you can index and slice array pointers, e.g. if a
is a pointer to array type:
a[x]
is shorthand for(*a)[x]
- and
a[low : high]
is shorthand for(*a)[low : high]
.
来源:https://stackoverflow.com/questions/43729893/where-does-go-define-that-p-field-as-opposed-to-p-field-is-a-valid-syntax-e