Go语言方法和接收器类型详解

news2025/1/5 9:07:26

Go语言方法和接收器类型详解

1. 方法接收器类型

1.1 值接收器

值接收器方法不会改变接收器的状态,因为Go语言会在调用时复制接收器的值。因此,任何对接收器成员变量的修改都只会影响副本,而不会影响原始结构体实例。

type Person struct {
    Name string
    Age  int
}

// 值接收器方法
func (p Person) GetAge() int {
    return p.Age
}

func TestValueReceiver(t *testing.T) {
    p := Person{Name: "Tom", Age: 20}
    if age := p.GetAge(); age != 20 {
        t.Errorf("Expected age 20, got %d", age)
    }
    // p的值在方法调用后不会改变
}

1.2 指针接收器

指针接收器允许直接操作接收器本身,这意味着可以安全地修改接收器的字段,并且这些更改会持续存在。

// 指针接收器方法
func (p *Person) SetAge(age int) {
    p.Age = age
}

func TestPointerReceiver(t *testing.T) {
    p := &Person{Name: "Tom", Age: 20}
    p.SetAge(21)
    if p.Age != 21 {
        t.Errorf("Expected age 21, got %d", p.Age)
    }
    // p的值会被修改
}

2. 值类型和指针类型的方法调用

2.1 值类型调用指针接收器方法

func TestValueTypeCallPointerMethod(t *testing.T) {
    p := Person{Name: "Tom", Age: 20}
    p.SetAge(21) // Go 自动转换为 (&p).SetAge(21)
    if p.Age != 21 {
        t.Errorf("Expected age 21, got %d", p.Age)
    }
}

2.2 指针类型调用值接收器方法

func TestPointerTypeCallValueMethod(t *testing.T) {
    p := &Person{Name: "Tom", Age: 20}
    age := p.GetAge() // Go 自动转换为 (*p).GetAge()
    if age != 20 {
        t.Errorf("Expected age 20, got %d", age)
    }
}

3. 不可寻址的情况

3.1 Map值不可直接修改

func TestMapValueNotAddressable(t *testing.T) {
    people := make(map[string]Person)
    people["tom"] = Person{Name: "Tom", Age: 20}
    
    // 错误做法
    // people["tom"].Age = 21
    
    // 正确的做法
    person := people["tom"]
    person.Age = 21
    people["tom"] = person
    
    if people["tom"].Age != 21 {
        t.Errorf("Expected age 21, got %d", people["tom"].Age)
    }
}

3.2 临时值不可寻址

func TestTemporaryValueNotAddressable(t *testing.T) {
    // 以下代码会编译错误
    // Person{Name: "Tom", Age: 20}.SetAge(21)
    
    // 可以调用值接收器方法
    age := Person{Name: "Tom", Age: 20}.GetAge()
    if age != 20 {
        t.Errorf("Expected age 20, got %d", age)
    }
}

3.3 字面量不可寻址

func TestLiteralNotAddressable(t *testing.T) {
    // 以下代码会编译错误
    // (&struct{ name string }{"tom"}).name = "jerry"
    
    // 正确的做法是先赋值给变量
    p := Person{Name: "Tom", Age: 20}
    p.SetAge(21)
    if p.Age != 21 {
        t.Errorf("Expected age 21, got %d", p.Age)
    }
}

3.4 Map值是指针类型的情况

func TestMapWithPointerValues(t *testing.T) {
    // 创建一个字符串到 *Person 的映射
    people := make(map[string]*Person)
    
    // 添加一个新的 Person 到映射中
    people["tom"] = &Person{Name: "Tom", Age: 20}
    
    // 直接修改 tom 的年龄
    people["tom"].Age = 21
    
    if people["tom"].Age != 21 {
        t.Errorf("Expected age 21, got %d", people["tom"].Age)
    }
}

4. Map值的正确修改方式

  • 获取值的副本
  • 修改副本
  • 将修改后的副本存回map

5. 方法调用的自动转换

5.1 值到指针的自动转换

  • Go编译器自动处理从值到指针的转换
  • 允许值类型调用指针接收器方法

5.2 指针到值的自动转换

  • Go编译器自动处理从指针到值的转换
  • 允许指针类型调用值接收器方法

注意事项

  1. 选择接收器类型时考虑:

    • 是否需要修改接收器状态
    • 性能考虑
    • 接口实现要求
  2. 处理不可寻址情况:

    • 使用中间变量
    • 正确处理map值的修改
    • 注意指针类型的使用
  3. 使用map存储指针时:

    • 可以直接修改指针指向的对象
    • 确保指针正确初始化
    • 考虑并发安全问题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2269434.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何将联系人从Android转移到 OPPO? [解决了]

概括 OPPO Reno4系列预计将于2020年10月1日上午9点30分举行线上发布会。从其官方预告片中我们不难发现,OPPO Reno4旗舰手机试图诠释梦想、挑战、勇气、自信和可能性。 3D曲面屏,图形流畅,机身更轻薄,色彩真实。听起来棒极了&…

uniapp 微信小程序开发使用高德地图、腾讯地图

一、高德地图 1.注册高德地图开放平台账号 (1)创建应用 这个key 第3步骤,配置到项目中locationGps.js 2.下载高德地图微信小程序插件 (1)下载地址 高德地图API | 微信小程序插件 (2)引入项目…

Rabbitmq追问2

分析rabbitmq 默认使用姿势是什么 direct fanout还是什么 public void convertAndSend(String exchange, String routingKey, Object object, CorrelationData correlationData) throws AmqpException { this.send(exchange, routingKey, this.convertMessageIfNecessary(obje…

工作中常用Vim的命令

Hi, 我是你们的老朋友,主要专注于嵌入式软件开发,有兴趣不要忘记点击关注【码思途远】 目录 0. ctags -R 1.认识 Vim的几种工作模式 2.高频使用命令 2.1 修改文件 2.2 关于行号 2.3 删除多行,删除部分 2.4 复制粘贴 2.5 光标移动 2.…

【ComfyUI + 自定义节点】图片叠加掩膜(mask)部分扣掉(变黑)

Comfyui的官方示例:https://github.com/comfyanonymous/ComfyUI/blob/master/custom_nodes/example_node.py.example 一、代码 ( 逻辑:将图片对应掩膜覆盖的区域替换为黑色) 因为comfyui加载的图片后,转化为tensor i…

RocketMQ学习笔记(持续更新中......)

目录 1. 单机搭建 2. 测试RocketMQ 3. 集群搭建 4. 集群启动 5. RocketMQ-DashBoard搭建 6. 不同类型消息发送 1.同步消息 2. 异步消息发送 3. 单向发送消息 7. 消费消息 1. 单机搭建 1. 先从rocketmq官网下载二进制包,ftp上传至linux服务器&#xff0c…

【二】arcgis JavaScript api 实现加载不同坐标系的底图和三维服务

提示:如果是天地图底图参考这篇文章 【一】arcgis JavaScript api 实现加载不同坐标系的底图和三维服务_arcgis js api 调用三维地图服务-CSDN博客 需求: 前端开发实现底图(wkid:3857,web墨卡托)&#x…

PDF怎么压缩得又小又清晰?5种PDF压缩方法

PDF 文件在日常办公与学习中使用极为频繁,可想要把它压缩得又小又清晰却困难重重。一方面,PDF 格式本身具有高度兼容性,集成了文字、图像、矢量图等多样元素,压缩时难以兼顾不同元素特性,稍不注意,文字就会…

数据结构与算法之动态规划: LeetCode 62. 不同路径 (Ts版)

不同路径 https://leetcode.cn/problems/unique-paths/description/ 描述 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “…

Edge如何获得纯净的启动界面

启动Edge会出现快速链接,推广链接,网站导航,显示小组件,显示信息提要,背景 ●复杂页面 ●精简页面 点击页面设置按钮 关闭快速链接 关闭网站导航 关闭小组件 关闭信息提要 关闭背景 关闭天气提示 精简页面看起来十分舒…

如何利用java爬虫获得AMAZON商品详情

在数字化时代,数据的价值不言而喻,尤其是对于电商平台而言,获取商品的详细信息对于优化用户体验、制定营销策略至关重要。亚马逊作为全球最大的电商平台之一,拥有海量的商品信息。本文将介绍如何使用Java编写爬虫程序,…

人工智能基础软件-Jupyter Notebook

简介: Jupyter Notebook是基于网页的用于交互计算的应用程序。其可被应用于全过程计算:开发、文档编写、运行代码和展示结果。 Jupyter Notebook是以网页的形式打开,可以在网页页面中直接编写代码和运行代码,代码的运行结果也会直…

数据库系列之分布式数据库下误删表怎么恢复?

数据的完整性是数据库可用性的基本功能,在实际应用数据库变更操作过程中可能因为误操作导致误删表或者truncate操作影响业务的正常访问。本文介绍了分布式数据库中在误删表场景下的数据恢复方案,并进行了对比。 1、数据库误删表恢复方案 应用数据的完整…

【分布式缓存中间件Memcached原理与应用】

分布式缓存中间件(以 Memcached 为例) 一、分布式缓存中间件概述 (一)概念 分布式缓存中间件是一种用于存储频繁访问的数据副本的软件系统,它位于应用程序和数据源(通常是数据库)之间。通过在…

No.2十六届蓝桥杯备战|练习题4道|数据类型|字符型|整型|浮点型|布尔型|signed|unsigned(C++)

B2002 Hello,World! - 洛谷 #include <iostream> using namespace std; int main() { cout << "Hello,World!" << endl; return 0; }打印飞机 #include <iostream> using namespace std;int main() {cout << " …

mysql系列7—Innodb的redolog

背景 本文涉及的内容较为底层&#xff0c;做了解即可&#xff0c;是以前学习《高性能Mysql》和《mysql是怎样运行的》的笔记整理所得。 redolog(后续使用redo日志表示)的核心作用是保证数据库的持久性。 在mysql系列5—Innodb的缓存中介绍过&#xff1a;数据和索引保存在磁盘上…

小程序租赁系统开发的优势与应用探索

内容概要 在如今这个数码科技飞速发展的时代&#xff0c;小程序租赁系统开发仿佛是一张神奇的魔法卡&#xff0c;能让租赁体验变得顺畅如丝。想象一下&#xff0c;无论你需要租用什么&#xff0c;从单车到房屋&#xff0c;甚至是派对用品&#xff0c;只需动动手指&#xff0c;…

太速科技-135-4路250Msps 16bit AD采集PCIe卡

4路250Msps 16bit AD采集PCIe卡 一、板卡概述 板卡为四路250M频率采集卡&#xff0c;可以实现四路高速的模拟数据转换到PCI-E总线上。板载两颗250M采样频率的高性能AD芯片&#xff08;ADS42LB69&#xff09;&#xff0c;数据输出模式为LVDS&#xff08;DDR&#xff09…

如何恢复永久删除的PPT文件?查看数据恢复教程!

可以恢复永久删除的PPT文件吗&#xff1f; Microsoft PowerPoint应用程序是一种应用广泛的演示程序&#xff0c;在人们的日常生活中经常使用。商人、官员、学生等在学习和工作中会使用PowerPoint做报告和演示。PowerPoint在人们的学习和工作生活中占主导地位&#xff0c;每天都…

Windows电脑带有日历的桌面备忘记事工具

工作计划、备忘清单、会议文件等怎么能化繁琐为简约&#xff0c;统统存储在一个记事工具中呢&#xff1f;Windows电脑上的备忘记事工具哪一款好用呢&#xff1f;推荐大家可关注敬业签&#xff0c;敬业签是一款集备忘、提醒和日历等功能于一体的桌面记事工具&#xff0c;可悬挂桌…