Golang中值类型/指针类型的差异

时间:2018-07-14 01:57:04

标签: go

type T struct {
    Name string
}
func (t T) M1 () {
    t.Name = "name1"
}
func (t *T) M2 () {
    t.Name = "name2"
}
type intf interface {
    M1()
    M2()
}
func main() {
    var t1 T = T{"t1"}
    t1.M1()
    t1.M2()
    var t2 intf = t1
    t2.M1()
    t2.M2()
}

为什么我使用var tf intf = &t1,这是正确的 但是当我使用var tf intf = &t1时,这是不正确的 两种表示形式有什么区别吗?

1 个答案:

答案 0 :(得分:2)

  

当我使用var tf intf =&t1时,这是正确的,但是当我使用var tf intf =&t1时,它不是

由于在您的示例中,您使用的是tf intf = t1(并且它没有编译),所以我想您可能是说:

  

当我使用var tf intf =&t1时,这是正确的但是当我使用var tf intf = t1时,它不是

所以这里的问题是,为什么&T{"t1"}(指针)满足接口intf,而T{"t1"}(值)却没有满足接口。

在您的示例中,该接口具有两种方法M1M2

类型T实现了两种方法 BUT

  • M1具有T value 作为接收者
  • M2以T pointer 作为接收者

那么为什么编译器会考虑使用T指针来实现两个方法,却认为T值没有实现?

可以在规范中找到答案:

https://golang.org/ref/spec#Method_sets

  

任何其他类型T的方法集都包含以接收者类型T声明的所有方法。相应的指针类型* T的方法集是所有以接收者* T或T声明的方法的集合(也就是说,包含方法集T)。

规范说,T指针具有用接收者T*T定义的所有方法(因此在这种情况下,M1和M2都一样)。

但是值T仅具有用接收者T定义的方法(因此在这种情况下只有M1)。

由于接口同时具有这两种方法,因此只有指针可以实现它。