[英]Types of Go struct methods that satisfy an interface
给出以下 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
但不能从一个tourGuide
。
谁能告诉我为什么会这样? 为什么我可以调用t1.hello()
和t1.goodbye()
但不知何故t1
对接口greeter
是不够的?
如果您有一个指向结构的指针,那么 go 将允许您访问结构上的属性及其具有值类型接收器(与指针接收器相关)的函数,而无需取消引用您的指针,但这仅适用于一级指针,请参阅下面的代码,其中我将 t2 转换为指向tourguide
的指针,此时我需要明确取消引用它以使其重新成为指向tourguide
的指针。 将指向结构的指针的第一级视为一种特殊情况,它允许您使用语法糖来访问值类型的属性和函数,从而不必经常手动取消对变量的引用。
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 tmpT2 *tourGuide = &tourGuide{"Smith"}
var t2 **tourGuide = &tmpT2
(*t2).hello() // Hello Smith
(*t2).goodbye() // Goodbye Smith (same as (*t2).hello())
//illegal: t1 is not assignable to g1 (why?)
//var g1 greeter = t1
//now this is illegal too
//var g2 greeter = t2
var g3 greeter = (*t2)
g3.hello() // Hello Smith
g3.goodbye() // Goodbye Smith
}
我在这里的回答解释了为什么 Go 会阻止您获取存储在接口中的值的地址。
TL;博士其因为一个指向其中,当不同类型B的值随后被存储在接口指向的接口的类型A的值将被无效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.