假设我们了解到, 用于类型明确的方法定义X,GO编译器隐式定义了相同的方法类型*X和 反之亦然 ,如果我声明, func (c Cat) foo(){ //do stuff_ } 并宣布 func (c *Cat) foo(){ // do stuff_ } 然后GO编译器给出错误, Compile error: method re-declared 这表明,指针方法是隐式定义的, 反之亦然
假设我们了解到,
用于类型明确的方法定义X,GO编译器隐式定义了相同的方法类型*X和 反之亦然 ,如果我声明,
X
*X
func (c Cat) foo(){ //do stuff_ }
并宣布
func (c *Cat) foo(){ // do stuff_ }
然后GO编译器给出错误,
Compile error: method re-declared
这表明,指针方法是隐式定义的, 反之亦然
在下面的代码中,
package main type X interface{ foo(); bar(); } type Cat struct{ } func (c Cat) foo(){ // do stuff_ } func (c *Cat) bar(){ // do stuff_ } func main() { var c Cat var p *Cat var x X x = p // OK; *Cat has explicit method bar() and implicit method foo() x = c //compile error: Cat has explicit method foo() and implicit method bar() }
GO编译器出现错误,
cannot use c (type Cat) as type X in assignment: Cat does not implement X (bar method has pointer receiver)
在x = c,因为隐式指针方法满足接口,但是隐式非指针方法不满足。
x = c
题:
为什么隐式非指针方法不满足接口?
让我们看一下语言规范:
类型可能具有与之关联的 方法集 。接口类型的方法集是其接口。任何其他类型T的方法集都包含以接收者类型T声明的所有方法。相应指针类型 T的方法集是所有以接收者 T或T声明的方法的集合(也就是说,它还 包含方法 T 集 )。
在您的示例中,接口类型的方法集x为[foo(), bar()]。该类型的方法集Cat是[foo()],与该类型的方法组*Cat是[foo()]+ [bar()]= [foo(), bar()]。
x
[foo(), bar()]
Cat
[foo()]
*Cat
[bar()]
这解释了为什么变量p满足接口x,而变量c却不满足。
p
c