有点困惑为什么结构体实现接口函数时候 不用结构体指针
有点困惑为什么结构体实现接口函数时候 不用结构体指针,而且我试过用结构体鱼指针报错
type lunchCompany interface {
play()
}
func eat(w lunchCompany) {
w.play()
fmt.Println("eat function")
}
type moveInfo struct {
id int
name string
}
func (mov moveInfo) play() {
fmt.Printf("play the movie")
}
main 函数
var test6 lunchCompany = moveInfo{453, "teet"}
eat(test6)
这样才对但是如果moveinfo 改成指针那个就不对
正在回答 回答被采纳积分+1
1.核心规则:谁实现了接口?
在 Go 语言中,接口的实现取决于方法的接收者类型。
如果方法是值接收者,例如:func (m moveInfo) play()
那么:moveInfo 结构体本身实现了接口,*moveInfo 指针也自动实现了接口。
结果:赋值时用 moveInfo{} 或者 &moveInfo{} 都可以。
如果方法是指针接收者,例如:func (m *moveInfo) play()
那么:只有 *moveInfo 指针才算实现了接口,moveInfo 结构体本身不算。
结果:赋值时必须使用 &moveInfo{},否则编译器会报错。
2. 为什么改成指针接收者后,传值会报错?
当你写 var test6 lunchCompany = moveInfo{453, teet} 时,你是在把一个值赋值给接口。
如果接口要求的函数定义在指针上,Go 编译器不会自动帮你把这个值变成指针。
原因有两点:
第一是安全性。指针接收者通常意味着你想修改结构体内部的数据。如果你传的是值,接口内部存的是一份拷贝。改动拷贝的数据对原数据没有意义,Go 为了防止这种逻辑错误,直接在编译阶段禁止了这种做法。
第二是地址问题。并不是所有的值都是可以取地址的(比如某些临时变量),如果 Go 允许这种行为,可能会导致程序在运行时因为找不到地址而崩溃。
3.什么时候该用指针接收者?
虽然你现在的代码用值接收者没问题,但以下两种情况你必须改用指针接收者并配合 & 符号使用:
情况一:你需要在方法内部修改结构体的成员变量(比如修改 id 或 name)。
情况二:结构体非常大。如果用值接收者,每次调用接口都会完整拷贝一遍结构体,非常浪费内存和性能。
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星