【发布时间】:2016-12-07 10:33:09
【问题描述】:
给出以下 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 是addressable)或*T 调用带有*T 接收器的方法。我了解编译器会处理此处的差异(请参阅代码中的我的 cmets)。
但是,当我们实现接口时,情况会发生变化。在上面的代码中,greeter 接口类型的变量可以从指向tourGuide 的指针赋值,但不能从tourGuide 赋值。
谁能告诉我为什么会这样?为什么我可以调用t1.hello() 和t1.goodbye() 但不知何故t1 对接口greeter 不够用?
【问题讨论】:
-
谢谢。但我的问题是,为什么编译器允许使用值类型和指针调用带有值和指针接收器的结构方法。但是不提供类似的接口支持吗?可能更多的是设计问题,而不是语言的工作原理?
-
@danze 如果这是一个设计问题,那么它不适合 SO。
-
@Volker 我的问题源于不完全理解 Go 接口,而接受的答案为我澄清了这一点。这不是设计问题。
标签: pointers go methods struct interface