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

时间:2016-09-15 02:59:54

标签: go

我发现值类型和引用类型之间的接口可满足性令人困惑。我仍然无法弄清楚它如何在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但是类型* Counter1没有。所以& c1不应该分配给i1;类型Counter2不满足fmt.Stringer但是* Counter2类型,所以c2不应该分配给i2,实际上它不能。这个测试程序的结果对我来说没有意义。我认为它可能是某种语法糖,go编译器会自动在引用类型和值类型之间进行转换。但是下面的测试代码让我更加困惑:

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。但是第一次和第二次分配仍然有效。这对我没有意义。

1 个答案:

答案 0 :(得分:3)

  

在Go中,选择器表达式(x.f)表示值f(或有时x)的字段或方法*x

基本上,在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()调用它的方法。