news 2026/4/20 12:37:23

Go进阶之理解方法本质

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Go进阶之理解方法本质

Go语言虽然不支持经典的面向对象的语法元素.比如继承 对象和类.Go语言也有方

法.和函数相比就是在声明形式上多了一个参数.Go称为receiver参数.receiver是参

数与类型之间的纽带.

方法声明格式:

func (receiver T/* T) MethodName(参数列表) (返回值列表){ //方法体 }

方法声明的T称为receiver的基类型.通过receiver.上述方法被绑定到类型T上.伪代码如下:

var t T t.methodName(参数列表) var pt *T = &t pt.methodName(参数列表)

    1.Go方法特点:

    1).方法名的首字母是否大写决定了该方法是不是导出方法.

    2).方法定义要与类型定义放在同一个包内.由此可以知道不能为原生类型(如int

    float64 map等)添加方法.只能为自定义类型定义方法.示例如下.

    type MyInt int64 func (i MyInt) String() string { return "自定义类型的方法" }

    同理可以得出不能跨域Go包为其他包内的自定义类型定义方法.

    3).每个方法只能有一个receiver参数.不支持多receiver参数列或变长receiver参

    数.一个方法只能绑定一个基类型.Go语言不支持同时绑定多个类型的方法.

    4).receiver参数的基类型本身不能是指针类型或者接口类型.示例如下.

    2.方法的本质:

    Go语言没有类.方法与类别通过reveiver联系到一起,可以为任何非内置原生类型定

    义方法.示例如下:

    type T struct { a int } func (t T) get() int { return t.a } func (t *T) set(a int) { t.a = a }

    receiver其实是作为第一个参数传入方法列表中.上述的方法可以等价转换为下面的

    函数,代码如下:

    func Get(t T) int { return t.a } func Set(t *T, a int) { t.a = a }

    这种转换后的函数就是方法的原型.只不过在Go语言中.这种等价转换是由Go编译器

    在编译和生成代码时自动完成的.Go语言规范中提供了一个新的概念.可以更充分理解

    等价转换.

    Go方法一般使用方式:

    func Test() { var t T t.get() t.set(1000) }

    等价替换:

    func ChangeTest() { var t T T.get(t) (*T).set(&t, 1000) }

    这种直接以类型名T调用方法的表达式被称为方法表达式.类型T只能调用T的方法集

    合(Method Set)中的方法.同理.*T只能调用*T的方法集合中的方法.这种通过方法表

    达式进行调用的方式与我们之前所做的方法到函数的等价转换如出一辙.这就是Go方

    法的本质.一个方法所绑定类型实例为第一个参数的普通函数.

    Go方法本身就是一个普通函数.我们甚至可以把它作为右值赋值给函数类型的变量.

    func Test() { var t T f1 := (*T).set f2 := T.get f1(&t,1) fmt.Println(f2(t)) }

    3.选择正确的reveiver类型:

    方法和函数的等价变换公式:

    func(t T) M1()<=> M1(t T) func(t *T) M2()<=> M2(t *T)

    M1方法的receiver参数类型为T.M2方法的receiver参数类型为*T.

    1).receiver类型为T时:

    选择以T作为receiver参数类型时.T的M1方法等价于M1(t T).Go函数的参数采用的

    是值复制传递.也就是说M1函数体中的t是T类型的一个副本.这样在M1函数实现中对

    参数t做任何修改都只会影响副本.不会影响到原T类型.

    2).receiver类型为*T时:

    选择以*T作为receiver参数类型时.T的M2方法等价为M2(t *T).我们传递给M2函

    数的t是T类型实例的地址.这样M2函数体中对参数t做的任何修改都会反应到原T类

    型实例上.

    示例如下:

    func main() { //t.a=0 var t T fmt.Println(t.a) t.M1() fmt.Println(t.a) t.M2() fmt.Println(t.a) } type T struct { a int } func (t T) M1() { t.a = 10 } func (t *T) M2() { t.a = 11 }

    执行结果:

    疑惑:是不是T类型实例只能调用receiver为T的类型方法.不能调用receiver为*T类

    型的方法呢.答案是否定.无论T类型实例还是*T类型实例.都既可以调用receiver为T

    类型的方法.也可以调用receiver为*T类型的方法.示例如下:

    func main() { var t T var pt = &T{} t.M1() t.M2() pt.M1() pt.M2() }

    可以看到上述都可以进行互相调用.实际上这都是Go语法糖.Go编译器在编译和生成

    代码时为我们做了自动转换.

    总结:

    如果要对类型实例进行修改.可以为receiver选择*T类型.

    如果没有对类型实例修改的需求.可以为receiver选择T类型或*T类型均可.如果类型

    的size过大的话.选择指针会更好一些.

    微笑着孤言寡语.

    如果大家喜欢我的分享的话.可以关注我的微信公众号

    念何架构之路

    版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
    网站建设 2026/4/17 2:19:55

    SMB挂载与iSCSI挂载飞牛存储:你该选择哪一种连接方式?

    作为一个刚刚跨入“私有云”大门的小白&#xff0c;面对飞牛存储后台里那两个让人头大的选项——SMB挂载和iSCSI挂载&#xff0c;你是不是也感觉像在选修天文学还是量子物理&#xff1f; 别担心&#xff0c;今天我们就用“人话”来聊聊这事儿&#xff0c;保证不出现一句让你想…

    作者头像 李华
    网站建设 2026/4/16 14:29:41

    大规模语言模型在个性化职业规划中的应用

    大规模语言模型在个性化职业规划中的应用 关键词:大规模语言模型、个性化职业规划、职业分析、职业推荐、职业发展路径 摘要:本文深入探讨了大规模语言模型在个性化职业规划领域的应用。首先介绍了研究的背景、目的、预期读者、文档结构和相关术语。接着阐述了大规模语言模型…

    作者头像 李华
    网站建设 2026/4/15 22:04:29

    FHIR 资源查询实战指南:从 HTTP 接口到 Java 客户端的完整实现

    一、前言&#xff1a;为什么需要理解 FHIR 查询&#xff1f; 在医疗健康信息系统中&#xff0c;FHIR&#xff08;Fast Healthcare Interoperability Resources&#xff09;已成为事实上的数据交换标准。无论是设备管理、任务审批、还是患者服务&#xff0c;我们常常需要回答这…

    作者头像 李华
    网站建设 2026/4/18 19:40:17

    微服务架构设计大比拼:独立数据库 VS 集中式DAO,谁才是真香定律?

    前言各位码农朋友们&#xff0c;今天咱们来聊一个让人又爱又恨的话题——微服务的数据层设计。相信不少小伙伴都经历过这样的场景&#xff1a;领导一拍脑袋说要搞微服务拆分&#xff0c;结果拆着拆着就发现&#xff0c;哎呀&#xff0c;数据库连接不够用了&#xff01;这感觉就…

    作者头像 李华
    网站建设 2026/4/18 5:11:57

    YOLO26改进策略【Backbone/主干网络】| 替换骨干网络为CVPR-2024 PKINet 获取多尺度纹理特征,适应尺度变化大的目标

    一、本文介绍 本文记录的是利用PKINet优化YOLO26的目标检测方法研究。 在遥感图像目标检测中,目标尺度变化大,本文引入PKINet来捕获多尺度纹理特征,并在YOLO26的基础上配置了原论文中PKINET_T, PKINET_S, PKINET_B三种模型,以满足不同的需求。 文章目录 一、本文介绍 二、…

    作者头像 李华
    网站建设 2026/4/17 7:23:13

    基于STM32单片机噪音计检测系统 声音大小检测 噪音等级 DIY

    目录STM32单片机噪音计检测系统概述硬件组成软件设计DIY步骤应用场景源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;STM32单片机噪音计检测系统概述 该系统基于STM32单片机设计&#xff0c;用于检测环境中的声音大小和噪音等级。通过麦…

    作者头像 李华