为什么取消引用地址会在golang中产生“无效的间接”错误?
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
}
为什么我们不能执行取消引用的对象点字段名称而不是地址点字段名称?请阅读问题解释的代码注释,我在这里遗漏了什么?
回答
p.Name并按p.Age原样工作,因为如果p是指向结构的指针,则p.Name是(*p).Name. 引用规范:选择器:
在表达式
x.f[...] 中,如果 of 的类型x是定义的指针类型并且(*x).f是表示字段(但不是方法)的有效选择器表达式,x.f则是(*x).f.
鉴于此,*p.Name它不会尝试取消引用p和引用Name字段,而是尝试取消引用p.Name不是指针的字段。
如果您使用括号对间接寻址进行分组,则它有效:
fmt.Println((*p).Name, (*p).Age)
但同样,由于这种形式非常频繁,Spec 允许您省略指针间接寻址,而只需编写p.Name.