Go 为什么取消对地址的引用会导致;“间接无效”;戈朗的错误?

Go 为什么取消对地址的引用会导致;“间接无效”;戈朗的错误?,go,pointers,memory-address,dereference,Go,Pointers,Memory Address,Dereference,为什么我们不能执行取消引用的对象点域名称而不是地址点域名称?请阅读代码注释以了解问题解释,我在这里缺少什么?p.Name和p.Age按原样工作,因为如果p是指向结构的指针,那么p.Name是(*p.Name)的缩写。引用 在表达式x.f[…]中,如果x的类型是定义的指针类型,(*x).f是表示字段(但不是方法)的有效选择器表达式,x.f是(*x).f的缩写 有鉴于此,*p.Name不会尝试取消引用p并引用Name字段,它会尝试取消引用不是指针的p.Name字段 如果使用括号对间接寻址进行分组,则

为什么我们不能执行取消引用的对象点域名称而不是地址点域名称?请阅读代码注释以了解问题解释,我在这里缺少什么?

p.Name
p.Age
按原样工作,因为如果
p
是指向结构的指针,那么
p.Name
(*p.Name)的缩写。引用

在表达式
x.f
[…]中,如果
x
的类型是定义的指针类型,
(*x).f
是表示字段(但不是方法)的有效选择器表达式,
x.f
(*x).f
的缩写

有鉴于此,
*p.Name
不会尝试取消引用
p
并引用
Name
字段,它会尝试取消引用不是指针的
p.Name
字段

如果使用括号对间接寻址进行分组,则它可以工作:

type person struct{
  Name string
  Age int
}

// parameters : (pointer to person struct), which is basically address of person object
func printPerson(p *person) {

  // when we add '*' to a address, then it becomes dereferencing, Hence 
  // I read "*p.Name" as "person object dot Name" and i expect it to give value,
  // I get this error:
  // ./prog.go:20:15: invalid indirect of p.Name (type string)
  // ./prog.go:20:24: invalid indirect of p.Age (type int)
  fmt.Println(*p.Name, *p.Age) // does not works, ERROR THROWN

  // But this works perfectly
  // I read it as "person address dot name and person address dot age"
  // for me it does not make sense when we say "address dot field name", 
  // shouldn't it be "object dot field name ? "
  fmt.Println(p.Name, p.Age)
}
func main() {
  p := person{"foobar", 23}
  printPerson(&p) // we are sending address to the method
}

但是,由于这种形式非常常见,规范允许您省略间接指针,只需在Go中写入
p.Name

&
运算符用作指向变量的指针,并将其地址保存在内存中<代码>*
可用于“取消引用”此类指针。取消对指针的引用使我们能够访问指针指向的值

在您的示例中,当函数收到参数
&p
(指向变量p的指针)时,您可以直接更改其值,因为结构“person”的成员
name
age
不是指针(*T)

在这种情况下,您要将struct
person
的成员更改为指针类型(如下面的示例中),它将打印到控制台:指针值(内存地址)以及它们指向的var
foobar
age
的值

fmt.Println((*p).Name, (*p).Age)

谢谢,这个例子有助于更好地理解。
type person struct {
    Name *string // Pointer of type string
    Age  *int // Pointer of type int
}

func printPerson(p *person) {
    fmt.Println(p.Name, p.Age) // Pointer values (the memory addresses)
    fmt.Println(*p.Name, *p.Age) // Dereferenced values (foobar, 23)
}

func main() {
    name := "foobar"
    age := 23

    p := person{&name, &age}
    printPerson(&p)
}