有点困惑为什么结构体实现接口函数时候 不用结构体指针

有点困惑为什么结构体实现接口函数时候 不用结构体指针

有点困惑为什么结构体实现接口函数时候 不用结构体指针,而且我试过用结构体鱼指针报错

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回答
Moody 2026-04-10 23:17:01

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 星
云原生工程师
  • 参与学习       125    人
  • 解答问题       52    个

云时代,云原生工程师是一个前所未有的职业发展新机遇,2025学习正当时。资深云原生架构师亲授,快速构建完整理论体系,积累丰富企业级项目经验,轻松入行,保姆式教学服务+丰富辅助资料+就业指导+简历指导,

了解课程
请稍等 ...
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师