在 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() 调用 TeacherShowB() 方法,尽管 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 语言中值接收者和指针接收者方法调用的自动转换规则详解的更多相关文章

  1. UIViewController中各方法调用顺序及功能详解

    UIViewController中各方法调用顺序及功能详解 UIViewController中loadView, viewDidLoad, viewWillUnload, viewDidUnload, ...

  2. 转:UIViewController中各方法调用顺序及功能详解

    UIViewController中loadView, viewDidLoad, viewWillUnload, viewDidUnload, viewWillAppear, viewDidAppear ...

  3. C++中值传递、指针传递、引用传递的总结

    C++中值传递.指针传递.引用传递的总结   指针传递和引用传递一般适用于:函数内部修改参数并且希望改动影响调用者.对比值传递,指针/引用传递可以将改变由形参"传给"实参(实际上就 ...

  4. R语言中样本平衡的几种方法

    R语言中样本平衡的几种方法 在对不平衡的分类数据集进行建模时,机器学习算法可能并不稳定,其预测结果甚至可能是有偏的,而预测精度此时也变得带有误导性.在不平衡的数据中,任一算法都没法从样本量少的类中获取 ...

  5. 机器学习中的隐马尔科夫模型(HMM)详解

    机器学习中的隐马尔科夫模型(HMM)详解 在之前介绍贝叶斯网络的博文中,我们已经讨论过概率图模型(PGM)的概念了.Russell等在文献[1]中指出:"在统计学中,图模型这个术语指包含贝叶 ...

  6. JSON创建键值对(key是中文或者数字)方式详解

    JSON创建键值对(key是中文或者数字)方式详解 先准备好一个空的json对象 var obj = {}; 1. 最原始的方法 obj.name = 'zhangsan'; //这种方式很简单的添加 ...

  7. Opencv中Mat矩阵相乘——点乘、dot、mul运算详解

    Opencv中Mat矩阵相乘——点乘.dot.mul运算详解 2016年09月02日 00:00:36 -牧野- 阅读数:59593 标签: Opencv矩阵相乘点乘dotmul 更多 个人分类: O ...

  8. 【翻译】Anatomy of a Program in Memory—剖析内存中的一个程序(进程的虚拟存储器映像布局详解)

    [翻译]Anatomy of a Program in Memory—剖析内存中的一个程序(进程的虚拟存储器映像布局详解) . . .

  9. MySQL中tinytext、text、mediumtext和longtext等各个类型详解

    转: MySQL中tinytext.text.mediumtext和longtext等各个类型详解 2018年06月13日 08:55:24 youcijibi 阅读数 26900更多 个人分类: 每 ...

  10. JAVA高级架构师基础功:Spring中AOP的两种代理方式:动态代理和CGLIB详解

    在spring框架中使用了两种代理方式: 1.JDK自带的动态代理. 2.Spring框架自己提供的CGLIB的方式. 这两种也是Spring框架核心AOP的基础. 在详细讲解上述提到的动态代理和CG ...

随机推荐

  1. Pycharm+pytest+allure打造高逼格的测试报告

    环境前置提示:allure是基于Java的一个程序,需要Java1.8的环境,没有安装需要去安装一下. 如果在cmd中能输入java,获取到命令信息则不管,否则需要配置系统变量: 路径:计算机> ...

  2. 如何对jar包修改并重新发布在本机

    本人苦于jieba不能如何识别伊利丹·怒风,召唤者坎西恩这种名字,对jieba-analysis进行了解包和打包 步骤1:找到对应jar 步骤2:在cmd中输入jar -xvf xxx.jar解压包, ...

  3. C#/.NET/.NET Core优秀项目和框架2024年7月简报

    前言 公众号每月定期推广和分享的C#/.NET/.NET Core优秀项目和框架(每周至少会推荐两个优秀的项目和框架当然节假日除外),公众号推文中有项目和框架的介绍.功能特点.使用方式以及部分功能截图 ...

  4. SEO自动外链蜘蛛池工具促进百度快速收录怎么样 跟大家详谈一下

    此工具集成市面上所有自动外链网站的资源链接,经过合并.去重.筛选.验证 总结出最终的外链资源 ,软件实时更新 本软件将您繁杂的外链推广转为自动化进行,并且加入站群的支持,您只需要将你的站群域名粘贴到软 ...

  5. 【Kafka】03 Shell 操作

    查看Kafka主题列表 $KAFKA_HOME/bin/kafka-topics.sh \ --zookeeper centos7-02:2181,centos7-03:2181,centos7-04 ...

  6. MyBatis-Plus文件上传方法

    网站的文件上传方法 本地存储上传 // 本地存储方式 MultipartFile接受文件 @PostMapping("/save") public Result save(Stri ...

  7. Ubuntu18.04 系统环境下 vscode中忽略pylint某些错误或警告

    相关: ubuntu18.04系统环境下使用vs code安装pylint检查python的代码错误 ====================================== 假设已经在前文(ht ...

  8. .NET 屏幕录制

    窗口/屏幕截图适用于截图.批注等工具场景,时时获取窗口/屏幕图像数据流呢,下面讲下视频会议共享桌面.远程桌面这些场景是如何实现画面录制的. 常见的屏幕画面时时采集方案,主要有GDI.WGC.DXGI. ...

  9. 15-canvas渐变色

    1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="U ...

  10. SMU 2024 spring 天梯赛自主训练2

    SMU 2024 spring 天梯赛自主训练2 7-1 I Love GPLT - SMU 2024 spring 天梯赛自主训练2 (pintia.cn) PHP 点击查看代码 I L o v e ...