首先看一段代码:
// typeAssert project main.go
package main
import (
"fmt"
)
type Student struct {
name string
}
type Ione interface {
getName() string
}
type Itwo interface {
getName() string
setName(name string)
}
func (s Student) getName() string {
return s.name
}
func (s *Student) setName(name string) {
s.name = name
}
func main() {
// 申明一个接口对象
var i Ione
// 定义一个Student结构体变量
s := Student{}
// 向上赋值
i = s
_, ok := i.(Student)
fmt.Println(ok)
}
上面的代码很简单,诸位可以复制运行。
问题:当我把函数
func (s Student) getName() string {
return s.name
}
的receiver改成指针类型,即写成如下:
func (s *Student) getName() string {
return s.name
}
编译马上报错。很奇怪这是为什么????
自己在工作的过程当中也写了半年的go语言,今天一看这个问题突然懵逼了,所以去学习了一下文档。在此回馈题主。
首先我们定义上面的一个类型A。假设现在我们想定义一个对象并且调用hello方法的时候,可以采取以下两种形式:
正常来讲,因为hello这个函数的reciver是指针类型,那么我们理所应当应该使用A对象的指针来调用,也就是第二种形式。那么为何第一种也可以呢?因为go在背后帮我们做了转换。实际上,A和*A本身是两种不同的类型,当我们使用a.hello()的时候,go会自动帮我们转换成(&a).hello()的形式。
golang中没有像C++语言中this这种隐含的设定,reciver看起来和this差不多,实际上它也是其所在函数的一个参数。如上面例子中的hello方法,功能上是等价于下面这个函数的。
所以我们可以以另一种形式来调用hello
hello是为*A类型定义的一个函数,word是为A类型定义的一个函数。
如果现在有一个interface
Ione类型的对象只能被复制为A的指针类型的值,因为一个有特定method的inteface只能被赋值一个实现了该interface内所有方法的对象。而且,根据上面的代码我们可以看出来,*A类型才实现了hello方法,A类型只实现了word方法,所以,将A类型的对象直接赋值给Ione类型的对象是不能通过编译的。
如果我说的还不理解,可以看下官网的文档
https://golang.org/ref/spec#M...