Where does Go define that p.Field (as opposed to (*p).Field) is a valid syntax even when p is a pointer to a struct?

寵の児 提交于 2021-02-17 02:17:23

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!