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编译器自动处理从指针到值的转换
- 允许指针类型调用值接收器方法
注意事项
-
选择接收器类型时考虑:
- 是否需要修改接收器状态
- 性能考虑
- 接口实现要求
-
处理不可寻址情况:
- 使用中间变量
- 正确处理map值的修改
- 注意指针类型的使用
-
使用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中,实现动态切换菜单通过组件化开发和Vue的响应式数据绑定来实现。 示例: 展示如何创建一个可以动态切换菜单的Vue组件。 首先,需要定义一个Vue组件,该组件将包含菜单项和用于切换菜单的状态。 1. 创建Vue组件 <t…...
如何在 Ubuntu 22.04 上优化 Apache 以应对高流量网站教程
简介 在本教程中,我们将学习如何优化 Apache 以应对高流量网站。 当运行高流量网站时,确保你的 Apache Web 服务器得到优化对于有效处理负载至关重要。在本指南中,我们将介绍配置 Apache 以提高性能和可扩展性的基本技巧。 为高流量网站优…...
17爬虫:关于DrissionPage相关内容的学习01
概述 前面我们已经大致了解了selenium的用法,DerssionPage同selenium一样,也是一个基于Python的网页自动化工具。 DrissionPage既可以实现网页的自动化操作,也能够实现收发数据包,也可以把两者的功能合二为一。 DressionPage的…...
【HarmonyOS之旅】HarmonyOS概述(一)
目录 1 -> HarmonyOS简介 2 -> HarmonyOS发展历程 3 -> HarmonyOS技术特性 3.1 -> 硬件互助,资源共享 3.1.1 -> 分布式软总线 3.1.2 -> 分布式设备虚拟化 3.1.3 -> 分布式数据管理 3.1.4 -> 分布式任务调度 3.1.5 -> 分布式连接…...
chatwoot 开源客服系统搭建
1. 准备开源客服系统(我是用的Chatwoot ) 可以选择以下开源客服系统作为基础: Chatwoot: 开源,多语言,跟踪和分析,支持多渠道客户对接,自动化和工作流等。源码Zammad: 现代的开源工单系统。Fr…...
30分钟搭建 Typecho 个人博客教程
Typecho是一款PHP博客程序,相比于WordPress,Typecho显得更加的轻量级和简洁。现在越来越多的人倾向于用Typecho来搭建个人博客——众所周知,能跑WordPress的机器都不便宜。 Typecho是一款国人团结打造的开源博客系统,和WordPress…...
智能工厂的设计软件 应用场景的一个例子:为AI聊天工具添加一个知识系统 之7 附件(文档)
为AI聊天工具添加一个知识系统 Part1 人性化&去中心化 前情提要 这一次我们暂时抛开前面对“智能工厂的软件设计”的考虑--其软件智能 产品就是 应用程序。直接将这些思维方式和方法论 运用在其具体应用场景中。本文是其中的一个应用场景。 今天用了 一个新的AI助手工具…...
鸿蒙应用开发启航计划
以前有过简单的学习了解,但是现在工作内容的原因,要专门搞这个,因此需要更加熟练地掌握鸿蒙应用开发。 1.开发IDE -- DevEco Studio Windows环境 运行环境要求 为保证DevEco Studio正常运行,建议电脑配置满足如下要求ÿ…...
基本算法——回归
目录 创建工程 加载数据 分析属性 创建与评估回归模型 线性回归 回归树 评估 完整代码 结论 本节将通过分析能源效率数据集(Tsanas和Xifara,2012)学习基本的回归算法。我们将基 于建筑的结构特点(比如表面、墙体与屋顶面…...
深度学习——神经网络中前向传播、反向传播与梯度计算原理
一、前向传播 1.1 概念 神经网络的前向传播(Forward Propagation)就像是一个数据处理的流水线。从输入层开始,按照网络的层次结构,每一层的神经元接收上一层神经元的输出作为自己的输入,经过线性变换(加权…...
解决git push报错:not valid: is this a git repository?
今天想把代码更新到仓库里,执行git push origin master:main的时候报错:not valid: is this a git repository? 查了好多方法都没用。后来经过这篇文章的启发:https://zhuanlan.zhihu.com/p/301518109 可能是由于校园网的问题,…...
树形查询转成TreeNode[],添加新节点
在使用PrimeVue的TreeTable组件时,需要将带有层级的数据转换为TreeNode[]类型的数据结构。TreeNode是PrimeVue中定义的一个接口,用于表示树节点。通常,带有层级的数据是一个嵌套的对象或数组,其中每个对象可能包含子对象ÿ…...
【Rust自学】8.2. Vector + Enum的应用
8.2.0. 本章内容 第八章主要讲的是Rust中常见的集合。Rust中提供了很多集合类型的数据结构,这些集合可以包含很多值。但是第八章所讲的集合与数组和元组有所不同。 第八章中的集合是存储在堆内存上而非栈内存上的,这也意味着这些集合的数据大小无需在编…...
攻防世界web第十题Web_python_template_injection
这是题目,从题目上看是一个python模板注入类型的题目。 首先测试是否存在模板注入漏洞,构造http://61.147.171.105:57423/{{config}} 得到 说明存在模板注入漏洞,继续注入 构造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 在本次深入研究中,我们将从基础开始,逐步了解 API 设计,并逐步实现定义卓越 API 的最佳实践。 作为开发人员,您可能熟悉其中的许多…...
ROUGE指标在自然语言处理中的应用:从理论到实践
引言 你是否曾经遇到过机器生成的文本摘要与原文内容不符的情况?或者在使用机器翻译时,发现译文虽然“看起来”正确,但语义却与原文相差甚远?在自然语言处理(NLP)领域,如何科学地评估生成文本的…...
GraalVM:云原生时代的Java虚拟机
1. 概述 GraalVM是由Oracle公司开发的一款高性能、多语言的虚拟机平台。它不仅兼容传统的JVM字节码执行,还引入了即时编译(JIT)技术的革新,以及对多种编程语言的支持。GraalVM旨在通过提供更高效的执行环境来满足云计算环境中日益…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...
LabVIEW双光子成像系统技术
双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制,展现出显著的技术优势: 深层组织穿透能力:适用于活体组织深度成像 高分辨率观测性能:满足微观结构的精细研究需求 低光毒性特点:减少对样本的损伤…...
BLEU评分:机器翻译质量评估的黄金标准
BLEU评分:机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域,衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标,自2002年由IBM的Kishore Papineni等人提出以来,…...
React父子组件通信:Props怎么用?如何从父组件向子组件传递数据?
系列回顾: 在上一篇《React核心概念:State是什么?》中,我们学习了如何使用useState让一个组件拥有自己的内部数据(State),并通过一个计数器案例,实现了组件的自我更新。这很棒&#…...
