我发现值类型和引用类型之间的接口可满足性令人困惑。我仍然不明白它在高朗语中是如何运作的。考虑这段程序:
type Counter1 int
type Counter2 int
func (c Counter1) String() string {
}
func (c *Counter2) String() string {
}
func main() {
var c1 Counter1
var c2 Counter2
var i1 fmt.Stringer = &c1 // assignment 1
var i2 fmt.Stringer = c2 // assignment 2
}
然而,赋值1有效,赋值2无效。我希望它们都不能工作:类型Counter1满足fmt。Stringer但是type *Counter1没有。所以&c1不能赋值给i1;类型Counter2不满足fmt。但是字符串类型*Counter2可以,所以c2不应该分配给i2,实际上它不能。这个测试程序的结果对我来说不合理。我想这可能是某种语法糖,编译器在引用类型和值类型之间自动转换。然而,下面的测试代码让我更困惑:
type Test interface {
f()
g()
}
func (c Counter1) f() {
}
func (c *Counter1) g() {
}
func receiveTest(t Test) {
}
func main() {
......
var c3 Counter1
var p3 Test = &c3 // works
receiveTest(&c3) // works
receiveTest(c3) // doesn't work
}
类型*Counter1和类型Counter1都不满足接口Test。然而,第一次和第二次赋值仍然有效。我看不懂。
在Go语言中,选择表达式(
x.f
)表示值x
(有时为*x
)的字段或方法f
。
基本上,在Go中,如果你在一个方法上有一个指针接收器,你不必写&object.method()
,但你可以只写object.method()
因为接口在Go语言中是隐式的,只要对象本身不是指针,那么满足接口的方法是否有指针接收器并不重要,它们仍然会被用来满足接口。
因此,在您的示例中,Counter1
结构体可以同时调用f()
和g()
方法,但*Counter1
只能调用g()
方法。