为什么隐式非指针方法不满足接口?

ove*_*nge 5 methods interface go structural-typing

假设我们有这样的理解,

用于类型明确的方法定义X,GO编译器隐式定义了相同的方法类型*X反之亦然,如果我声明,

func (c Cat) foo(){
  //do stuff_
} 
Run Code Online (Sandbox Code Playgroud)

并声明,

func (c *Cat) foo(){
  // do stuff_
}
Run Code Online (Sandbox Code Playgroud)

然后GO编译器给出错误,

Compile error: method re-declared
Run Code Online (Sandbox Code Playgroud)

这表明,指针方法是隐式定义的,反之亦然


在下面的代码中,

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

}
Run Code Online (Sandbox Code Playgroud)

GO 编译器报错,

cannot use c (type Cat) as type X in assignment:
    Cat does not implement X (bar method has pointer receiver)
Run Code Online (Sandbox Code Playgroud)

at x = c,因为隐式指针方法满足接口,但隐式非指针方法不满足。

题:

为什么隐式非指针方法不满足接口?

dev*_*max 6

让我们看看语言规范

一个类型可能有一个与之关联的方法集。接口类型的方法集就是它的接口。任何其他类型 T 的方法集由所有以接收者类型 T 声明的方法组成。 对应指针类型 *T 的方法集是所有以接收者 *T 或 T 声明的方法的集合(即,它还包含方法组T)。

在您的示例中,接口类型的方法集x[foo(), bar()]. 该类型的方法集Cat[foo()],与该类型的方法组*Cat[foo()]+ [bar()]= [foo(), bar()]

这就解释了为什么 variablep满足 interface x,而 variablec不满足。