I have a simple code:
type Namer interface {
PrintName()
}
type P struct {
Name string
}
func (p *P) PrintName() {
fmt.Printf("%s
", p.Name)
}
func main() {
p := P{Name: "Name"}
var namers []Namer
namers = append(namers, &p)
fmt.Println(reflect.TypeOf(namers[0]))
on := &namers[0]
fmt.Println(reflect.TypeOf(on))
(*on).PrintName()
(**on).Name = "EEEE"
(*on).PrintName()
}
and bunch of questions :)
Thanks for help!
P doesn't implement interface Namer, only *P does, as PrintName() is defined on *P.
As I understand it, TypeOf(namers[0]) is *P because you're inspecting the actual slice element itself, and TypeOf can see inside the interface. With TypeOf(&namers[0]) you're merely taking the address of the first element and inspecting its type (which is, of course, *Namer, as namers is a slice of Namer interface elements), without actually looking "inside" the element itself.
The last line doesn't print anything, because (**on).Name is not allowed. Change it to (*on).(*P).Name = "EEEE" and it works as intended.
I suppose - bear in mind I am not really proficient in GO - that the main reason for all of your questions is related to the fact that you implemented PrintName
in a way that the receiver (implementer) object is a pointer.
Assert that *on
is of type *P
. For example,
package main
import (
"fmt"
"reflect"
)
type Namer interface {
PrintName()
}
type P struct {
Name string
}
func (p *P) PrintName() {
fmt.Printf("%s
", p.Name)
}
func main() {
p := P{Name: "Name"}
var namers []Namer
namers = append(namers, &p)
fmt.Println(reflect.TypeOf(namers[0]))
on := &namers[0]
fmt.Println(reflect.TypeOf(on))
(*on).PrintName()
(*on).(*P).Name = "EEEE"
(*on).PrintName()
}
Output:
*main.P *main.Namer Name EEEE