给出以下 Go 代码示例:
package main
import "fmt"
type greeter interface {
hello()
goodbye()
}
type tourGuide struct {
name string
}
func (t tourGuide) hello() {
fmt.Println("Hello", t.name)
}
func (t *tourGuide) goodbye() {
fmt.Println("Goodbye", t.name)
}
func main() {
var t1 tourGuide = tourGuide{"James"}
t1.hello() // Hello James
t1.goodbye() // Goodbye James (same as (&t1).goodbye())
var t2 *tourGuide = &tourGuide{"Smith"}
t2.hello() // Hello Smith
t2.goodbye() // Goodbye Smith (same as (*t2).hello())
// illegal: t1 is not assignable to g1 (why?)
// var g1 greeter = t1
var g2 greeter = t2
g2.hello() // Hello Smith
g2.goodbye() // Goodbye Smith
}
我能够使用类型为tourGuide的变量t1或指向tourGuide的指针t2调用结构体tourGuide的两种方法。换句话说,我可以使用类型T或*T的变量调用具有T接收器的方法。类似地,如果T是可寻址的,则我可以使用类型T的变量(而不是*T)调用具有*T接收器的方法。我理解编译器在这里处理差异(请参见我的代码注释)。
然而,在实现接口时情况会发生改变。在上面的代码中,greeter接口的变量可以从tourGuide的指针分配,但不能从tourGuide分配。
有人能告诉我为什么会这样吗?为什么我能调用t1.hello()和t1.goodbye(),但是t1对于接口greeter来说不够?