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
}
why can't we execute dereferenced object dot field name instead of address dot field name ? Please read code comments for question explanation, what am i missing here ?
p.Name
and p.Age
work as-is, because if p
is a pointer to a struct, then p.Name
is a shorthand for (*p).Name
. Quoting from Spec: Selectors:
In the expression
x.f
[...] if the type ofx
is a defined pointer type and(*x).f
is a valid selector expression denoting a field (but not a method),x.f
is shorthand for(*x).f
.
In the light of this, *p.Name
does not try to dereference p
and refer to the Name
field, it tries to dereference the p.Name
field which is not a pointer.
If you use parenthesis to group the indirection, it works:
fmt.Println((*p).Name, (*p).Age)
But again, since this form is very frequent, the Spec allows you to omit the pointer indirection and simply write p.Name
.