当前位置: 首页 > news >正文

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

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

1. 方法接收器类型

1.1 值接收器

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

type Person struct {Name stringAge  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 = 21people["tom"] = personif 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 = 21if 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存储指针时:

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

相关文章:

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

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

Flutter:打包apk,详细图文介绍(一)

困扰了一天,终于能正常打包apk安装了,记录下打包的流程。建议参考我这篇文章时,同时看下官网的构建说明。 官网构建并发布 Android 应用详情 1、AS创建Flutter项目 2、cmd执行命令 生成一个sunluyi.jks的文件,可以自行把sunluyi替…...

Vue.js组件开发-实现动态切换菜单简单示例

在Vue.js中&#xff0c;实现动态切换菜单通过组件化开发和Vue的响应式数据绑定来实现。 示例&#xff1a; 展示如何创建一个可以动态切换菜单的Vue组件。 首先&#xff0c;需要定义一个Vue组件&#xff0c;该组件将包含菜单项和用于切换菜单的状态。 1. 创建Vue组件 <t…...

如何在 Ubuntu 22.04 上优化 Apache 以应对高流量网站教程

简介 在本教程中&#xff0c;我们将学习如何优化 Apache 以应对高流量网站。 当运行高流量网站时&#xff0c;确保你的 Apache Web 服务器得到优化对于有效处理负载至关重要。在本指南中&#xff0c;我们将介绍配置 Apache 以提高性能和可扩展性的基本技巧。 为高流量网站优…...

17爬虫:关于DrissionPage相关内容的学习01

概述 前面我们已经大致了解了selenium的用法&#xff0c;DerssionPage同selenium一样&#xff0c;也是一个基于Python的网页自动化工具。 DrissionPage既可以实现网页的自动化操作&#xff0c;也能够实现收发数据包&#xff0c;也可以把两者的功能合二为一。 DressionPage的…...

【HarmonyOS之旅】HarmonyOS概述(一)

目录 1 -> HarmonyOS简介 2 -> HarmonyOS发展历程 3 -> HarmonyOS技术特性 3.1 -> 硬件互助&#xff0c;资源共享 3.1.1 -> 分布式软总线 3.1.2 -> 分布式设备虚拟化 3.1.3 -> 分布式数据管理 3.1.4 -> 分布式任务调度 3.1.5 -> 分布式连接…...

chatwoot 开源客服系统搭建

1. 准备开源客服系统&#xff08;我是用的Chatwoot &#xff09; 可以选择以下开源客服系统作为基础&#xff1a; Chatwoot: 开源&#xff0c;多语言&#xff0c;跟踪和分析&#xff0c;支持多渠道客户对接&#xff0c;自动化和工作流等。源码Zammad: 现代的开源工单系统。Fr…...

30分钟搭建 Typecho 个人博客教程

Typecho是一款PHP博客程序&#xff0c;相比于WordPress&#xff0c;Typecho显得更加的轻量级和简洁。现在越来越多的人倾向于用Typecho来搭建个人博客——众所周知&#xff0c;能跑WordPress的机器都不便宜。 Typecho是一款国人团结打造的开源博客系统&#xff0c;和WordPress…...

智能工厂的设计软件 应用场景的一个例子:为AI聊天工具添加一个知识系统 之7 附件(文档)

为AI聊天工具添加一个知识系统 Part1 人性化&去中心化 前情提要 这一次我们暂时抛开前面对“智能工厂的软件设计”的考虑--其软件智能 产品就是 应用程序。直接将这些思维方式和方法论 运用在其具体应用场景中。本文是其中的一个应用场景。 今天用了 一个新的AI助手工具…...

鸿蒙应用开发启航计划

以前有过简单的学习了解&#xff0c;但是现在工作内容的原因&#xff0c;要专门搞这个&#xff0c;因此需要更加熟练地掌握鸿蒙应用开发。 1.开发IDE -- DevEco Studio Windows环境 运行环境要求 为保证DevEco Studio正常运行&#xff0c;建议电脑配置满足如下要求&#xff…...

基本算法——回归

目录 创建工程 加载数据 分析属性 创建与评估回归模型 线性回归 回归树 评估 完整代码 结论 本节将通过分析能源效率数据集&#xff08;Tsanas和Xifara&#xff0c;2012&#xff09;学习基本的回归算法。我们将基 于建筑的结构特点&#xff08;比如表面、墙体与屋顶面…...

深度学习——神经网络中前向传播、反向传播与梯度计算原理

一、前向传播 1.1 概念 神经网络的前向传播&#xff08;Forward Propagation&#xff09;就像是一个数据处理的流水线。从输入层开始&#xff0c;按照网络的层次结构&#xff0c;每一层的神经元接收上一层神经元的输出作为自己的输入&#xff0c;经过线性变换&#xff08;加权…...

解决git push报错:not valid: is this a git repository?

今天想把代码更新到仓库里&#xff0c;执行git push origin master:main的时候报错&#xff1a;not valid: is this a git repository? 查了好多方法都没用。后来经过这篇文章的启发&#xff1a;https://zhuanlan.zhihu.com/p/301518109 可能是由于校园网的问题&#xff0c;…...

树形查询转成TreeNode[],添加新节点

在使用PrimeVue的TreeTable组件时&#xff0c;需要将带有层级的数据转换为TreeNode[]类型的数据结构。TreeNode是PrimeVue中定义的一个接口&#xff0c;用于表示树节点。通常&#xff0c;带有层级的数据是一个嵌套的对象或数组&#xff0c;其中每个对象可能包含子对象&#xff…...

【Rust自学】8.2. Vector + Enum的应用

8.2.0. 本章内容 第八章主要讲的是Rust中常见的集合。Rust中提供了很多集合类型的数据结构&#xff0c;这些集合可以包含很多值。但是第八章所讲的集合与数组和元组有所不同。 第八章中的集合是存储在堆内存上而非栈内存上的&#xff0c;这也意味着这些集合的数据大小无需在编…...

攻防世界web第十题Web_python_template_injection

这是题目&#xff0c;从题目上看是一个python模板注入类型的题目。 首先测试是否存在模板注入漏洞&#xff0c;构造http://61.147.171.105:57423/{{config}} 得到 说明存在模板注入漏洞&#xff0c;继续注入 构造http://61.147.171.105:57423/{{‘’.class.mro}}: 得到 再构造…...

vmware 修改Ubuntu终端字体大小

1. 2、 3、 4、 5、 6、点击select...

API 设计:从基础到最佳实践

https://levelup.gitconnected.com/api-design-101-from-basics-to-best-practices-a0261cdf8886 在本次深入研究中&#xff0c;我们将从基础开始&#xff0c;逐步了解 API 设计&#xff0c;并逐步实现定义卓越 API 的最佳实践。 作为开发人员&#xff0c;您可能熟悉其中的许多…...

ROUGE指标在自然语言处理中的应用:从理论到实践

引言 你是否曾经遇到过机器生成的文本摘要与原文内容不符的情况&#xff1f;或者在使用机器翻译时&#xff0c;发现译文虽然“看起来”正确&#xff0c;但语义却与原文相差甚远&#xff1f;在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;如何科学地评估生成文本的…...

GraalVM:云原生时代的Java虚拟机

1. 概述 GraalVM是由Oracle公司开发的一款高性能、多语言的虚拟机平台。它不仅兼容传统的JVM字节码执行&#xff0c;还引入了即时编译&#xff08;JIT&#xff09;技术的革新&#xff0c;以及对多种编程语言的支持。GraalVM旨在通过提供更高效的执行环境来满足云计算环境中日益…...

Linux 信号集与信号掩码

目录 一、引言 二、信号集是什么 三、信号集关键函数 1.信号集的创建与初始化 2.信号的添加与删除 3.信号集的阻塞与解除阻塞 四、信号集实际应用场景 五、信号掩码的作用 六、信号掩码相关函数 1.sigprocmask 函数 2.sigemptyset 和 sigfillset 函数 七、信号掩码注…...

如何设置Edge浏览器访问软件

使用Edge浏览器访问分销ERP A\V系列软件时会出现各种报错&#xff0c;如何设置Edge浏览器使其正常访问&#xff0c;请看下面的具体操作。 一、打开Edge浏览器&#xff0c;点击右上角的 设置及其他&#xff0c;如图&#xff1a; 二、在弹出界面中&#xff0c;点击 扩展&#xff…...

DL笔记:旋转编码RoPE

1 背景 由于计算资源限制&#xff0c;目前的LLM大多在较短的上下文长度中进行训练&#xff0c;在推理中&#xff0c;如果超出预训练的长度&#xff0c;模型的性能将会显著降低 ——>需要一个可提供外推性的位置编码最经典的绝对位置编码就是原始Transformer中的那个sinusoi…...

C语言自定义类型与文件操作

构造类型 枚举类型 若定义不相关的常量使用宏定义&#xff1b;若定义一组相关的常量使用枚举。switch中case后访问的就是枚举。 定义&#xff1a; 我们一般情况下定义常量使用宏定义(#define)&#xff0c;宏定义适合没有关联关系的常量&#xff1b;但有时需要对一组有关联关系…...

《计算机网络A》单选题-复习题库解析-3

目录 106、MAN通常是指&#xff08; &#xff09; 107、下列因素中&#xff0c;不会影响信道数据传输速率的是&#xff08; &#xff09; 108、以太网交换机进行转发决策时使用的PDU地址是&#xff08; &#xff09; 109、下列机制中&#xff0c;可以解决因数据帧丢失而…...

VM虚拟机配置ubuntu网络

目录 桥接模式 NAT模式 桥接模式 特点&#xff1a;ubuntu的IP地址与主机IP的ip地址不同 第一部分&#xff1a;VM虚拟机给ubuntu的网络适配器&#xff0c;调为桥接模式 第二部分&#xff1a;保证所桥接的网络可以上网 第三部分&#xff1a;ubuntu使用DHCP&#xff08;默认&…...

【每日学点鸿蒙知识】Web高度适配、变量声明规范、动画取消、签名文件、包体积优化相关

1、HarmonyOS Web页面高度适配&#xff1f; 在Web页面设置高度100%时&#xff0c;发现和Web控件的高度不一致&#xff0c;这个需要设置什么可以达到页面高度和Web容器高度一致 目前只支持两种web布局模式&#xff0c;分别为Web布局跟随系统WebLayoutMode.NONE和Web基于页面大…...

uniapp使用ucharts组件

1.ucharts准备 有两种使用方式&#xff1a;一种是在uni的插件市场下载&#xff08;组件化开发&#xff09;。一种是手动引入ucharts包。官方都封装好组件了&#xff0c;我们不用岂不是浪费。 直接去dcloud插件市场&#xff08;DCloud 插件市场&#xff09;找&#xff0c;第一…...

LabVIEW工程师的未来发展

对于LabVIEW工程师以及更广义的编程从业者&#xff08;包括“高级民工”码农&#xff09;来说&#xff0c;随着AI技术和软件编程的逐步成熟&#xff0c;确实面临一些新的挑战和机遇。以下是对此问题的深入分析和未来方向的建议&#xff1a; 现状分析&#xff1a;技术过剩与竞争…...

java的bio、nio、aio 以及操作系统的select、poll、epoll

在 Java 和其他编程语言中&#xff0c;I/O 模型的选择对网络应用的性能和可扩展性有着重要影响。以下是 BIO&#xff08;Blocking I/O&#xff09;、NIO&#xff08;Non-blocking I/O&#xff09;、AIO&#xff08;Asynchronous I/O&#xff09;&#xff0c;以及操作系统级别的…...