Go 语言中值接收者和指针接收者方法调用的自动转换规则详解
在 Go 语言中,方法的调用规则对于值接收者和指针接收者有一些特别的行为,这使得代码变得更加简洁和易用。我们来详细解释一下“方法值调用规则”和“方法表达式调用规则”,以及它们如何影响代码的行为。
方法值调用(Method Value Call)
在 Go 中,方法调用的语法是 receiver.method(). 当一个方法具有接收者时,Go 允许我们在值接收者和指针接收者之间进行一定程度的自动转换。这些转换规则使得方法调用更加灵活。
自动获取地址
当你调用一个接收者为指针的方法时,如果你持有的是一个值,Go 会自动获取这个值的地址并传递给方法。反过来,如果你调用一个接收者为值的方法时,持有的是指针,Go 会自动解引用指针并传递给方法。
举例解释
假设我们有以下结构体和方法:
type Example struct {
Value int
}
func (e Example) ValueMethod() {
fmt.Println("ValueMethod called on", e.Value)
}
func (e *Example) PointerMethod() {
fmt.Println("PointerMethod called on", e.Value)
}
值接收者方法调用
var ex Example
ex.ValueMethod() // 直接调用,传递值
(&ex).ValueMethod() // 自动解引用 ex,传递值
指针接收者方法调用
var ex Example
ex.PointerMethod() // 自动获取 ex 的地址,传递指针
(&ex).PointerMethod() // 直接传递指针
在代码中的应用
type People struct{}
func (p *People) ShowA() {
fmt.Println("showA")
p.ShowB()
}
func (p *People) ShowB() {
fmt.Println("showB")
}
type Teacher struct {
People
}
func (t *Teacher) ShowB() {
fmt.Println("teacher showB")
}
func main() {
t := Teacher{}
t.ShowB()
}
t := Teacher{}创建了一个Teacher类型的值。t.ShowB()调用Teacher的ShowB()方法,尽管ShowB的接收者是*Teacher类型的指针,Go 自动获取t的地址并传递给方法,因此调用的是(&t).ShowB()。
type People struct{}
func (p People) ShowA() {
fmt.Println("showA")
p.ShowB()
}
func (p People) ShowB() {
fmt.Println("showB")
}
type Teacher struct {
People
}
func (t *Teacher) ShowB() {
fmt.Println("teacher showB")
}
func main() {
t := &Teacher{}
t.ShowB()
}
- 这样也能正常输出
为什么可以这样?
这是因为 Go 编译器知道 ShowB 方法需要一个指针接收者,并且在 t 是一个值时,它会自动获取 t 的地址以符合方法的签名。这使得方法调用更加直观,无需显式地获取地址。
总结
- 值接收者方法:可以使用值或者指针来调用。
- 指针接收者方法:可以使用指针或者值来调用,Go 会自动获取地址。
这种自动转换规则使得方法调用变得更加简洁,不需要显式地在值和指针之间转换,从而减少了代码的复杂性和易错性。
Go 语言中值接收者和指针接收者方法调用的自动转换规则详解的更多相关文章
- UIViewController中各方法调用顺序及功能详解
UIViewController中各方法调用顺序及功能详解 UIViewController中loadView, viewDidLoad, viewWillUnload, viewDidUnload, ...
- 转:UIViewController中各方法调用顺序及功能详解
UIViewController中loadView, viewDidLoad, viewWillUnload, viewDidUnload, viewWillAppear, viewDidAppear ...
- C++中值传递、指针传递、引用传递的总结
C++中值传递.指针传递.引用传递的总结 指针传递和引用传递一般适用于:函数内部修改参数并且希望改动影响调用者.对比值传递,指针/引用传递可以将改变由形参"传给"实参(实际上就 ...
- R语言中样本平衡的几种方法
R语言中样本平衡的几种方法 在对不平衡的分类数据集进行建模时,机器学习算法可能并不稳定,其预测结果甚至可能是有偏的,而预测精度此时也变得带有误导性.在不平衡的数据中,任一算法都没法从样本量少的类中获取 ...
- 机器学习中的隐马尔科夫模型(HMM)详解
机器学习中的隐马尔科夫模型(HMM)详解 在之前介绍贝叶斯网络的博文中,我们已经讨论过概率图模型(PGM)的概念了.Russell等在文献[1]中指出:"在统计学中,图模型这个术语指包含贝叶 ...
- JSON创建键值对(key是中文或者数字)方式详解
JSON创建键值对(key是中文或者数字)方式详解 先准备好一个空的json对象 var obj = {}; 1. 最原始的方法 obj.name = 'zhangsan'; //这种方式很简单的添加 ...
- Opencv中Mat矩阵相乘——点乘、dot、mul运算详解
Opencv中Mat矩阵相乘——点乘.dot.mul运算详解 2016年09月02日 00:00:36 -牧野- 阅读数:59593 标签: Opencv矩阵相乘点乘dotmul 更多 个人分类: O ...
- 【翻译】Anatomy of a Program in Memory—剖析内存中的一个程序(进程的虚拟存储器映像布局详解)
[翻译]Anatomy of a Program in Memory—剖析内存中的一个程序(进程的虚拟存储器映像布局详解) . . .
- MySQL中tinytext、text、mediumtext和longtext等各个类型详解
转: MySQL中tinytext.text.mediumtext和longtext等各个类型详解 2018年06月13日 08:55:24 youcijibi 阅读数 26900更多 个人分类: 每 ...
- JAVA高级架构师基础功:Spring中AOP的两种代理方式:动态代理和CGLIB详解
在spring框架中使用了两种代理方式: 1.JDK自带的动态代理. 2.Spring框架自己提供的CGLIB的方式. 这两种也是Spring框架核心AOP的基础. 在详细讲解上述提到的动态代理和CG ...
随机推荐
- Docker PHP容器安装composer
1.进入php容器docker exec -it cb6c1fe83bff(php容器ID) bash2.安装composerphp -r "copy('https://install.ph ...
- 后端报错记录:406/实体类getset缺失
报错为406:org.springframework.web.HttpMediaTypeNotAcceptableException 报错历程:在使用后端写neo4j的实体的时候忘记写@Data(没有 ...
- (六)Redis 消息队列 List、Streams
Redis 适合做消息队列吗?有什么解决方案?首先要明白消息队列的消息存取需求和工作流程. 1.消息队列 我们一般把消息队列中发送消息的组件称为生产者,把接收消息的组件称为消费者,下图是一个通用的消息 ...
- 【Java】项目采用的设计模式案例
先说一下业务需要: 做电竞酒店后台系统,第一期功能有一个服务申请的消息通知功能 就是酒店用户在小程序点击服务功能,可以在后台这边查到用户的服务需要 原本设计是只需要一张表存储这些消息,但是考虑设计是S ...
- 【Java】JDBC Part6 Apache-DBUtil & Spring-JdbcTemplate
Apache-DBUtils 开源的JDBC工具类,对JDBC的简单封装 SQL操作交给了QueryRunner的实例 Maven依赖 <!-- https://mvnrepository.co ...
- 【DataBase】局域网访问Windows系统下的MySQL8
Windows服务主机已经安装好MySQL8并且配置了用户密码 MySQL8更改用户密码: ALTER USER 'root'@'localhost' IDENTIFIED BY 'password' ...
- 强化学习:经典测试环境Cart-pole的原始文献
参考文献格式: A. G. Barto, R. S. Sutton, and C. W. Anderson. Neuronlike adaptive elements that can solve d ...
- 【转载】 MPP大规模并行处理架构详解
本文来自博客园,作者:五分钟学大数据 原文链接:https://www.cnblogs.com/itlz/p/14998858.html =============================== ...
- Linux环境下配置vscode的C/C++编译环境
操作系统环境: Linux 配置vscode的C/C++编译环境需要安装插件: 本文的配置是指在linux下不使用vscode插件中自动配置,而是采用手动编写配置文件.主要原因是插件自动生成的C/C ...
- baselines算法库的安装——Ubuntu20.04系统使用anaconda环境配置
baselines算法库不做过多介绍,个人认为这是公开是所有reinforcement learning算法库中最权威的,虽然没有后期更新,也就是没有了学术界的state of the art , ...