0

0

如何理解Golang指针接收者的作用_方法调用行为说明

P粉602998670

P粉602998670

发布时间:2026-01-19 12:07:46

|

117人浏览过

|

来源于php中文网

原创

指针接收者允许方法修改原始结构体字段,值接收者仅操作副本;指针接收者是接口实现和大结构体高效调用的必要选择,方法集差异决定接口赋值合法性。

如何理解golang指针接收者的作用_方法调用行为说明

指针接收者能让方法修改原始结构体字段

值接收者传入的是结构体副本,所有字段修改都只作用于副本,调用方的原始变量完全不受影响;指针接收者传入的是地址,方法内通过 p.Field = value 直接改写原始内存里的数据。

  • 必须用指针接收者才能实现状态变更,比如 func (u *User) SetEmail(email string)
  • 值接收者方法(如 func (u User) Name() string)天然适合只读计算,语义更清晰
  • Go 允许你用 user.SetEmail("a@b.c") 这种写法,即使 user 是值变量 —— 编译器自动转成 (&user).SetEmail(...),但前提是 user 必须是可寻址的(不能是字面量 User{}

接口赋值失败?大概率是忘了取地址

如果一个类型只用指针接收者实现了某个接口,那么只有 *T 能赋给该接口变量,T 会直接编译报错:cannot use t (type T) as type Interface in assignment

  • 错误示例:
    type Speaker interface { Speak() }
    type Dog struct{}
    func (d *Dog) Speak() { fmt.Println("Woof!") }
    
    var d Dog
    var s Speaker = d // ❌ 编译失败
  • 正确写法:s = &d 或构造时就用指针:s = &Dog{}
  • 混用值/指针接收者极易导致接口实现不一致:只要有一个方法用了指针接收者,建议全类型方法统一用指针,避免部分能赋值、部分不能的混乱

为什么大结构体一定要用指针接收者?

不是“一定”,而是“不这样做会付出明显代价”。假设结构体有 20 个字段(约 160 字节),每次调用值接收者方法都会复制整块内存 —— 对高频方法(如 String()MarshalJSON())就是隐性性能瓶颈

Vinteo AI
Vinteo AI

利用人工智能在逼真的室内环境中创建产品可视化。无需设计师和产品照片拍摄

下载
  • 指针接收者固定只传 8 字节(64 位系统),零拷贝
  • 标准库中几乎所有结构体方法(sync.Mutexbytes.Bufferhttp.Request)都用指针接收者,既是惯例,也是实践验证过的合理选择
  • 小结构体(如 type ID inttype Point struct{X,Y int})用值接收者反而更轻量,无须间接寻址

方法集(method set)决定接口能否被满足

Go 中「类型 T 的方法集」和「类型 *T 的方法集」是两个不同的集合。这是理解接口赋值行为的底层依据,不是语法糖,是硬性规则。

立即学习go语言免费学习笔记(深入)”;

  • T 的方法集:只包含值接收者方法(func (T) M()
  • *T 的方法集:包含值接收者 + 指针接收者方法(func (T) M()func (*T) M()
  • 所以 *T 总能赋给接口,而 T 只能在所有接口方法都是值接收者时才可赋值
  • 这个规则在嵌入结构体、泛型约束、类型断言时也会浮现,是容易被忽略但影响深远的一环
指针接收者不是语法装饰,它绑定着内存所有权、接口兼容性和运行时调度路径——哪怕你没显式写 &,Go 也在背后严格按这套规则做检查和分发。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

179

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

226

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

340

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

209

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

392

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

197

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

191

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

192

2025.06.17

PS使用蒙版相关教程
PS使用蒙版相关教程

本专题整合了ps使用蒙版相关教程,阅读专题下面的文章了解更多详细内容。

23

2026.01.19

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 8.4万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 3.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号