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

Go语言中值接收者和指针接收者的区别?

在 Go 语言中,值接收者指针接收者是方法定义中的两种接收者类型。它们的主要区别在于方法调用时的行为、接收者是否可以被修改,以及性能上的差异。


值接收者

定义

值接收者的方法接收的是调用对象的一个副本,方法内部对该副本的修改不会影响原对象。

特点

  1. 传递的是值的副本
    • 方法内操作的是值的拷贝,修改不会影响原对象。
  2. 适用于不可变的对象
    • 如果方法不需要修改对象的状态,可以使用值接收者。
  3. 适用于小对象
    • 值接收者传递整个对象副本,适合较小的对象。
  4. 可用值或指针调用
    • 无论是值还是指针,都可以调用值接收者的方法,Go 会自动处理。

示例

package mainimport "fmt"type Rectangle struct {Width, Height int
}// 值接收者方法
func (r Rectangle) Area() int {return r.Width * r.Height
}// 修改操作(仅对副本有效)
func (r Rectangle) SetWidth(w int) {r.Width = w
}func main() {rect := Rectangle{Width: 10, Height: 5}fmt.Println("Area:", rect.Area()) // 输出: Area: 50rect.SetWidth(20)fmt.Println("Width after SetWidth:", rect.Width) // 输出: Width after SetWidth: 10
}

说明:调用 SetWidth 方法时,rect.Width 没有改变,因为 SetWidth 操作的是值的副本。


指针接收者

定义

指针接收者的方法接收的是调用对象的地址,方法内部对接收者的修改会直接作用于原对象。

特点

  1. 传递的是指针
    • 方法操作的是对象的指针,修改接收者的状态会直接影响原对象。
  2. 适用于可变的对象
    • 如果方法需要修改对象的状态,必须使用指针接收者。
  3. 适用于大对象
    • 指针接收者避免了拷贝大对象的开销。
  4. 只能用值或指针调用
    • 无论对象是值还是指针,都可以调用指针接收者的方法,Go 会自动转换。

示例

package mainimport "fmt"type Rectangle struct {Width, Height int
}// 指针接收者方法
func (r *Rectangle) Scale(factor int) {r.Width *= factorr.Height *= factor
}func main() {rect := Rectangle{Width: 10, Height: 5}rect.Scale(2)fmt.Println("Scaled Width:", rect.Width) // 输出: Scaled Width: 20fmt.Println("Scaled Height:", rect.Height) // 输出: Scaled Height: 10
}

说明:调用 Scale 方法时,rect.Widthrect.Height 的值被直接修改。


值接收者与指针接收者的主要区别

特性值接收者指针接收者
传递内容对象的副本对象的地址
方法是否能修改原对象
适用场景- 不需要修改接收者
- 对象较小,拷贝开销小
- 需要修改接收者
- 对象较大,拷贝开销大
调用方式值或指针都可以调用值或指针都可以调用
性能较低性能:对于大对象,会复制整个对象较高性能:传递指针,避免了对象的复制

值接收者与指针接收者的调用规则

无论方法是值接收者还是指针接收者:

  1. 值调用值接收者:直接使用。
  2. 指针调用值接收者:Go 会自动解引用指针并传递对象值的副本。
  3. 值调用指针接收者:Go 会自动获取对象的地址。
  4. 指针调用指针接收者:直接使用。

示例

package mainimport "fmt"type Counter struct {Count int
}func (c Counter) Increment() {c.Count++
}func (c *Counter) Decrement() {c.Count--
}func main() {c := Counter{Count: 10}// 调用值接收者方法c.Increment()fmt.Println("After Increment:", c.Count) // 输出: After Increment: 10 (未修改)// 调用指针接收者方法c.Decrement()fmt.Println("After Decrement:", c.Count) // 输出: After Decrement: 9 (被修改)
}

如何选择值接收者或指针接收者?

  • 选择值接收者

    • 方法不需要修改接收者。
    • 对象较小(如基本数据类型或简单结构体)。
    • 提升代码可读性。
  • 选择指针接收者

    • 方法需要修改接收者。
    • 对象较大,拷贝成本高。
    • 需要保证方法在所有调用场景中的行为一致(如使用接口时,避免副本调用导致的问题)。

示例

如果结构体实现接口时:

  • 建议使用指针接收者,以确保通过接口调用时能修改对象。
type Resizable interface {Resize(factor int)
}type Rectangle struct {Width, Height int
}func (r *Rectangle) Resize(factor int) {r.Width *= factorr.Height *= factor
}

总结

  • 值接收者适合不可变操作;指针接收者适合可变操作。
  • 指针接收者避免了拷贝大对象的开销,但增加了代码复杂性。
  • 选择接收者类型时,应根据方法的用途和对象的大小权衡。

相关文章:

Go语言中值接收者和指针接收者的区别?

在 Go 语言中,值接收者和指针接收者是方法定义中的两种接收者类型。它们的主要区别在于方法调用时的行为、接收者是否可以被修改,以及性能上的差异。 值接收者 定义 值接收者的方法接收的是调用对象的一个副本,方法内部对该副本的修改不会影…...

kafka小实站

需要先在前面的文章里面照着下载好kafka,并且启动 先启动zookeeper 项目目录 package kafka; import lombok.extern.slf4j.Slf4j; import org.apache.kafka.clients.consumer.ConsumerRecord; import org.springframework.kafka.annotation.KafkaListener; import…...

基于Python实现车辆检测、机动车检测、识别位置标记、计数

目录 引言背景与应用场景车辆检测的研究意义相关工作车辆检测概述机动车检测方法分类基于传统计算机视觉的检测方法基于深度学习的检测方法技术与方法车辆检测技术概述基于Python的车辆检测方法图像处理与特征提取深度学习方法(如YOLO、SSD、Faster R-CNN等)数据集与标注常用…...

心理学硕士

心理学硕士的主要研究方向包括基础心理学、发展心理学和应用心理学‌。 基础心理学研究一般的心理现象与规律,如心理的实质及神经机制、感觉与知觉、意识与注意、学习与记忆、思维与语言、情绪与意识、人格等‌。发展心理学研究人类个体心理发生发展的特点和规律&a…...

python量化分析学习与实践1:API接口篇

业内比较流行的几款API数据接口,有聚宽、TuShare,yfinance,以及pandas的pandas_datareader等。国内的一般都需要用户认证,才能下载数据。国外的yfinance与pandas_datareader等则不需要,但需要科学上网。 聚宽 测试下…...

【GO基础学习】gin的使用

文章目录 模版使用流程参数传递路由分组数据解析和绑定gin中间件 模版使用流程 package mainimport ("net/http""github.com/gin-gonic/gin" )func main() {// 1.创建路由r : gin.Default()// 2.绑定路由规则,执行的函数// gin.Context&#x…...

网卡状态变更,virtio-net检测

实现方案: 现在在amp模式下linux端有个真实的物理网卡eth0,有一个虚拟网卡virtio-net0后端,此时需要一种机制,将真实物理网卡的状态发送rtos的virtio-net0前端。这里使用register_netdevice_notifier机制,每个virtio-n…...

中华人民共和国保守国家秘密法

中华人民共和国保守国家秘密法 (1988年9月5日第七届全国人民代表大会常务委员会第三次会议通过 2010年4月29日第十一届全国人民代表大会常务委员会第十四次会议第一次修订 2024年2月27日第十四届全国人民代表大会常务委员会第八次会议第二次修订) 目…...

ELK日志收集系统部署

1、 ElasticSearch部署 Elastic — 搜索 AI 公司 | Elastic 系统类型:Centos7.4 节点IP:172.16.246.234 软件版本:jdk-8u191-linux-x64.tar.gz、elasticsearch-6.5.4.tar.gz 示例节点:172.16.246.234 1、安装配置jdk8 ES运行依…...

3D线上艺术展:艺术与技术的完美融合

随着数字技术的飞速发展,未来的艺术展览正逐步迈向线上线下融合的新阶段。其中,3D线上展览以其独特的魅力,成为线下展览的延伸与拓展,为艺术爱好者们开辟了全新的观赏途径。 对于艺术家和策展人而言,3D线上展览不仅打…...

TiDB 的MPP架构概述

MPP架构介绍: 如图,TiDB Server 作为协调者,首先 TiDB Server 会把每个TiFlash 拥有的region 会在TiFlash上做交换,让表连接在一个TiFlash上。另外 TiFlash会作为计算节点,每个TiFlash都负责数据交换,表连接…...

Leetcode 10-正则表达式匹配/ 剑指 Offer 19. 正则表达式匹配

给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。 ‘.’ 匹配任意单个字符 ‘*’ 匹配零个或多个前面的那一个元素 所谓匹配,是要涵盖 整个 字符串 s 的,而不是部分字符串。 题解 字符串匹配多…...

FFmpeg 编码和解码

文章目录 音频格式AACADIF音频数据交换格式ADTS音频数据传输流 音频解码音频编码 视频格式H264GOP图像组I帧,P帧,B帧H264压缩技术H264压缩级别H264视频级别H264码流结构SPSPPS 解码视频编码视频 音频格式 AAC AAC全称 Advanced Audio Coding&#xff0…...

kali当中web扫描工具的用法

1. cadaver 用途&#xff1a;用于与WebDAV服务器交互&#xff0c;可进行文件上传、下载、目录浏览等操作。使用方法 连接到WebDAV服务器&#xff1a;cadaver <WebDAV服务器地址>&#xff0c;例如cadaver https://example.com/dav&#xff0c;然后按提示输入用户名和密码…...

深度剖析 Android Animation 框架

深度剖析 Android Animation 框架 目录 引言Android Animation 框架概述架构设计 3.1 核心类与接口3.2 动画类型3.3 动画执行流程使用指南 4.1 属性动画4.2 视图动画4.3 过渡动画设计模式 5.1 策略模式5.2 观察者模式5.3 工厂模式核心逻辑 6.1 动画插值器6.2 动画估值器6.3 动…...

泰山派GPIO子系统驱动---亮灯

本人linux驱动小白&#xff0c;文章基于B站up主 李Sir______ 视频内容记录&#xff0c;做笔记用。如有错误欢迎指正。本文将以开发板第40引脚GPIO3_B4作为LED灯珠的控制引脚&#xff0c;高电平灯亮&#xff0c;低电平灯灭。 杂话 在linux内核中&#xff0c;芯片厂商已经把所有…...

【C#特性整理】C#特性及语法基础

1. C#特性 1.1 统一的类型系统 C#中, 所有类型都共享一个公共的基类型. 例如&#xff0c;任何类型的实例都可以通过调用ToString方法将自身转换为一个字符串 1.2 类和接口 接口: 用于将标准与实现隔离, 仅仅定义行为,不做实现. 1.3 属性、方法、事件 属性: 封装了一部分对…...

Presence:Colyseus用于管理实时分布式数据的工具

Colyseus Presence 详细介绍 Presence 是 Colyseus 中用于管理实时分布式数据的一种工具。它主要用于在多房间、多服务器或分布式部署中实现玩家的实时在线状态、数据共享和通信。Presence 提供了一套简单的 API 来处理诸如在线玩家跟踪、分布式数据存储和发布/订阅模式等功能…...

Ubuntu 搭建SVN服务

目录 ​ 1、安装SVN服务端 2、创建SVN版本库 3、修改SVN配置svnserve.conf 3.1 配置文件介绍 3.2 svnserve.conf配置 3.3 authz配置设置用户读写权限 3.4 passwd配置 用户名密码 4、启动SVN服务 4.1 配置开机启动 1、安装SVN服务端 sudo apt-get install subversion…...

HTML速查

HTML 基本文档 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>文档标题</title></head><body>可见文本...</body> </html>基本标签&#xff08;Basic Tags&#xff09; <h1>最大的…...

day-102 二进制矩阵中的最短路径

思路 BFS 解题过程 从起点依次向八个方向尝试&#xff08;之后也一样&#xff09;&#xff0c;如果某个位置在矩阵内且值为0且没有访问过&#xff0c;将其添加到一个队列中&#xff0c;依次类推&#xff0c;直到到达出口 Code class Solution {public int shortestPathBinar…...

SQL Server大批量数据插入

数据库连接及相关操作 public class DataBase {/*** 驱动*/private static final String DRIVER PropertiesUtil.getString("spring.datasource.driver-class-name");/*** 数据库地址*/private static final String URL PropertiesUtil.getString("spring.da…...

在 Ubuntu 下通过 Docker 部署 Caddy 服务器

嘿&#xff0c;伙伴们&#xff01;今天我们来聊聊如何在 Ubuntu 系统下通过 Docker 部署 Caddy 服务器。Caddy 是一个现代的 Web 服务器&#xff0c;支持自动 HTTPS&#xff0c;简单易用&#xff0c;特别适合快速搭建网站。而 Docker 则是一个让你可以隔离和管理应用的神器。结…...

ZooKeeper注册中心实现

具体步骤 安装ZooKeeper&#xff08;启动端口占用&#xff0c;2181&#xff1a;客户端&#xff0c;8080&#xff1a;管理端&#xff09;引入客户端依赖实现注册中心接口SPI补充ZooKeeper注册中心 引入依赖 <!-- zookeeper --> <dependency><groupId>org.a…...

数仓建模:如何进行实体建模?

目录 1 如何进行实体建模? 业务建模 领域建模 逻辑建模 2 实体建模具体步骤 需求分析...

Python编程技术

设计目的 该项目框架Scrapy可以让我们平时所学的技术整合旨在帮助学习者提高Python编程技能并熟悉基本概念&#xff1a; 1. 学习基本概念&#xff1a;介绍Python的基本概念&#xff0c;如变量、数据类型、条件语句、循环等。 2. 掌握基本编程技巧&#xff1a;教授学生如何使…...

「Mac玩转仓颉内测版55」应用篇2 - 使用函数实现更复杂的计算

本篇教程基于仓颉编程语言扩展了计算器功能&#xff0c;支持加减乘除的基础运算&#xff0c;以及幂运算和开平方等高级功能。代码经过简化后&#xff0c;移除了对输入的复杂校验&#xff0c;提升了程序的可维护性和交互效率。 关键词 仓颉编程语言函数封装高级运算 一、功能说…...

map参数详解

const items new Array(15).fill(null).map((_, index) > ({key: index 1,label: nav ${index 1}, })); $.map() 函数用于使用指定函数处理数组中的每个元素(或对象的每个属性)&#xff0c;并将处理结果封装为新的数组返回。 注意&#xff1a;1. 在jQuery 1.6 之前&#…...

OSI 七层模型 | TCP/IP 四层模型

注&#xff1a;本文为 “OSI 七层模型 | TCP/IP 四层模型” 相关文章合辑。 未整理去重。 OSI 参考模型&#xff08;七层模型&#xff09; BeretSEC 于 2020-04-02 15:54:37 发布 OSI 的概念 七层模型&#xff0c;亦称 OSI&#xff08;Open System Interconnection&#xf…...

高转速风扇|无刷暴力风扇方案设计

在当今科技高速发展的时代&#xff0c;电子设备的性能不断提升&#xff0c;散热问题也日益成为关注的焦点。而 13w 高转速暴力风扇方案的出现&#xff0c;为解决各种设备的散热难题提供了强大的技术支持。 一、高转速暴力风扇的重要性 随着电子设备的不断升级&#xff0c;其功率…...