为什么引用类型可以分配给不满意的接口[golang]



我发现值类型和引用类型之间的接口可满足性令人困惑。我仍然不明白它在高朗语中是如何运作的。考虑这段程序:

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()

https://play.golang.org/p/nh8X-vwdfr

https://play.golang.org/p/1uKwZw6E-J

因为接口在Go语言中是隐式的,只要对象本身不是指针,那么满足接口的方法是否有指针接收器并不重要,它们仍然会被用来满足接口。

因此,在您的示例中,Counter1结构体可以同时调用f()g()方法,但*Counter1只能调用g()方法。

最新更新