Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Go 方法接收器:选择值接收器还是指针接收器?

Go 方法接收器:选择值接收器还是指针接收器?

作者头像
陈明勇
发布于 2023-05-24 06:56:05
发布于 2023-05-24 06:56:05
1.2K00
代码可运行
举报
文章被收录于专栏:Go技术干货Go技术干货
运行总次数:0
代码可运行

前言

许多 Go 初学者在方法接收器的选择上可能会感到困惑,不知道该选择值接收器还是指针接收器。本文将会对方法接收器进行介绍,并给出如何选择正确方法接收器的指导建议。

封面.png

方法接收器

Go 语言中,方法接收器是指在函数名前的参数,它作为方法的接收者,也就是该方法所属的类型。方法接收器可以是一个值类型(如 struct 或自定义类型),也可以是指向一个值类型的指针类型。

值接收器

值接收器是将类型的值作为方法接收器。

假设我们有一个结构体类型 Person

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
type Person struct {
   Name string
   Age  int
}

我们可以为 Person 结构体定义一个 SayHello 的方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func (p Person) SayHello() {
   fmt.Println("你好,我是陈明勇,请多指教!")
}

在这个方法的定义中,我们使用了一个值类型的接收器 (p Person)。这意味着任何 Person 类型的值或指针都可以调用 SayHello 方法,例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
p := Person{Name: "陈明勇", Age: 23}
p.SayHello()
p2 := &Person{Name: "陈明勇", Age: 23}
p2.SayHello()

指针接收器

指针接收器是将类型的指针作为方法接收器。

接着值接收器的代码例子,我们可以为 Person 结构体定义一个 SetName(name string) 方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func (p *Person) SetName(name string) {
   p.Name = name
}

在这个方法的定义中,我们使用了一个指针类型的接收器 (p *Person)。这意味着任何 Person 类型的指针都可以调用 SetName 方法,例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
p := Person{Name: "陈明勇", Age: 23}
p.SetName("Chen Mingyong")
fmt.Println(p)
p2 := &Person{Name: "陈明勇", Age: 23}
p2.SetName("Chen Mingyong")
fmt.Println(p2)

值接收器与指针接收器的比较

值接收器

  1. 当使用值接收器时,方法内部对接收器的修改不会影响到原始值。
  2. 指接收器可以接收类型的值和指针,如果是指针,在方法内部会被转为值。

指针接收器

  1. 当使用指针接收器时,方法内部对接收器的修改会影响到原始值。
  2. 指接收器可以接收类型的值和指针,如果是值,在方法内部会被转为指针。

如何选择正确的方法接收器

选择原则

在选择方法接收器时,我们需要考虑以下几个因素:

  1. 修改原始值的需求:如果方法需要修改接收器的值,那么应该使用 指针接收器。因为值接收器会创建原始值的副本,在方法内部对其进行的修改 不会 影响原始值。
  2. 数据结构大小:对于大型数据结构,使用 指针接收器 可以避免数据复制带来的性能开销。而对于较小的数据结构,使用 值接收器 可能不会带来明显的性能影响。
  3. 一致性:在同一个类型中,尽量保持 一致性,避免混用值接收器和指针接收器。这将有助于提高代码的可读性和可维护性。
  4. 安全性:值接收器不会修改原始值,因此在某些情况下可能更安全。如果需要 保护 原始数据不被意外修改,可以考虑使用 值接收器

实际开发中的一些建议

  1. 在实际开发中,尽量保持 一致性,避免在同一个类型中混用值接收器和指针接收器。
  2. 如果仍然 无法确定 使用哪种接收器,建议使用 指针接收器,因为它可以避免数据复制带来的性能开销。

小结

本文简单介绍了 Go 语言中的方法接收器,重点讲解了值接收器和指针接收器。通过实际示例展示了它们的用法,并对比了它们的差异性。最后,给出了如何根据实际情况正确选择接收器的建议。

总之,在选择接收器时,我们应考虑接收器类型的特性及使用场景,根据实际需求做出选择。若 无法确定 究竟使用哪种接收器,建议优先考虑 指针接收器

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-04-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Go技术干货 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Go高性能之方法接收器 - 指针vs值
如果您是 Go 新手,那么您一定遇到过方法和函数的概念。让我们找出两者之间的区别-
sunsky
2022/09/19
8010
Go高性能之方法接收器 - 指针vs值
Go小技巧&易错点100例(十五)
在Go程序中我们经常会对接口执行的耗时做一个记录,特别是针对核心或复杂业务的时候,我们需要关注该业务的执行耗时,可以具体到某个方法,有一个简单有效的技巧,你可以使用defer关键字,只需一行代码即可使用。例如:
闫同学
2024/04/20
1340
Go语言中的接收器与值传递详解
考虑一个简单的Circle类型,它有一个方法来计算圆的面积。我们可以定义一个非指针接收器来读取圆的半径。
GeekLiHua
2024/08/30
1250
Golang方法接收者
func(receiver receiver_type)some_func_name(arguments)return_values
有态度的马甲
2022/08/23
1K0
Go语言示例学习05-指针/结构体/方法/接口
在上面 *i 是创建了一个指针类型,&i 是获取指针的地址中的值,在上面示例中&i取到i的指针地址值
用户5252199
2022/04/18
2300
Go 1.23 新特性:slices 和 sync 等核心库的微调,大幅提升开发体验
Go 1.23 版本在北京时间 2024 年 8 月 14 日凌晨 1:03 发布。该版本带来了多项重大更新,具体内容可以参考我之前的文章:Go 1.23 版本发布啦,这些重大更新你一定要知道!。本文将重点介绍 slices、sync 等核心库的小改进。
陈明勇
2024/08/30
1.7K0
Go 1.23 新特性:slices 和 sync 等核心库的微调,大幅提升开发体验
Golang之旅15-方法和接收者
方法Method是种作用域特殊类型变量的函数,特定类型的变量称为接收者receiver。接收者类似Python中的self。方法的定义格式
皮大大
2021/03/02
4540
呜呜呜我要拿Go赢他~ 入门,基础语法Type 、interface、struct、*指针接收器
继续接入上章节的05-呜呜呜我要拿Go赢他~ 入门,Http库、基础语法type 的文章现在要学的是基础语法type
杨不易呀
2023/11/13
2790
呜呜呜我要拿Go赢他~ 入门,基础语法Type 、interface、struct、*指针接收器
go语言第六章(结构体与方法)
在 Go 语言中,结构体(struct)是一种自定义的数据类型,由一组具有不同类型的字段组成。而方法(method)则是一类特殊的函数,它与某个类型绑定,并可以访问和修改该类型的字段和属性。
GeekLiHua
2025/01/21
920
go语言第六章(结构体与方法)
GO系列(2)-interface特性
说明struct,在调用方法的时候,值类型既可以调用值接收者的方法,也可以调用指针接收者的方法;指针类型既可以调用指针接收者的方法,也可以调用值接收者的方法
爽朗地狮子
2022/10/20
2950
Java的类与Golang的结构体的区别
Java作为一门面向对象(OOP)的编程语言,它有类(class)的存在,而对于Golang,它不完全遵从OOP编程语言的设计思想,但它也有类似Java类的结构存在,那就是结构体(struct)。
程序新视界
2023/11/13
2540
Java的类与Golang的结构体的区别
Go 空结构体:零内存的魔力
在 Go 语言中,有一种特殊的用法可能让许多人感到困惑,那就是空结构体 struct{}。在本文中,我将对 Go 空结构体进行详解,准备好了吗?准备一杯你最喜欢的咖啡或茶,随着本文一探究竟吧。
陈明勇
2023/11/01
5340
Go 空结构体:零内存的魔力
Go方法 为什么推荐 使用指针类型的接收者
通过上面的示例,可以看出结构体的实例是一个值类型,在接收者是指针的方法中,依然可以访问到该值。这是因为实现了接收者是值类型的方法,相当于自动实现了接收者是指针类型的方法。反之,实现了接收者是指针类型的方法,不会自动实现接收者是值类型的方法。
兔云小新LM
2022/11/21
6620
Go语言进阶 | 深入理解深拷贝与浅拷贝
在Go语言的编程实践中,内存管理和数据复制是经常遇到的问题。特别是在处理复杂数据结构或自定义类型时,如何正确、高效地复制数据变得尤为重要。深拷贝与浅拷贝是处理数据复制时常用的两种策略,它们各自有着不同的应用场景和优缺点。
windealli
2024/03/16
7800
Go语言进阶 | 深入理解深拷贝与浅拷贝
Go Struct function “指针接收者” 与 “值接收者” 区别
在 Go 语言中,函数与方法代表不同的概念,函数是独立的,方法是指结构体方法,它依赖于结构体,但两者皆以关键字 func 定义,只是定义方式略有不同。
软件书桌
2024/05/10
2240
golang新手容易犯的3个错误
这是因为代码中只是声明了map的类型,却没有为map创建底层数组,此时的map实际上在内存中还不存在,即nil map,可以运行下面的代码进行验证:
李海彬
2018/09/29
1.4K0
golang新手容易犯的3个错误
Go 编程 | 连载 16 - 结构体 Struct
在基本数据类型中的 byte 和 rune 其实就是 uint8 和 int32 的别名,在源码中这些别名就是使用 type 关键字定义的,当然我们也可以自己定义别名。
RiemannHypothesis
2022/09/28
3240
Golang Interface 详解(上)
  独特的“非侵入式”接口设计是 Go 语言的一亮点。接口使得 Go 这种静态型语言有了动态型语言的特性,提供了非常大的灵活性。Go 语言的成功,接口功不可没。
Se7en258
2023/05/18
2770
Golang Interface 详解(上)
Go语言——方法
⽅法总是绑定对象实例,并隐式将实例作为第⼀实参 (receiver),方法的语法如下:
传说之下的花儿
2023/04/16
2640
Golang面向对象中易混淆的几个概念
篇外话:从事云计算后端项目非前端开发,若时间有限,值得深入接触的编程语言有4门:c/java/go/rust,若有余力,每个语言都可以深入接触。至于Python语言,可以利用其在配置脚本领域的优势,和bash,perl一样当配置脚本语言,工具语言使用,Python不太适合大型的后端项目开发。
后端云
2022/11/25
4260
推荐阅读
相关推荐
Go高性能之方法接收器 - 指针vs值
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验