Go语言中的接收器(Receiver)详解

news2025/1/9 23:44:38

在 Go 语言中,接收器(Receiver) 是指在方法声明中与方法绑定的对象。它是 Go 语言实现面向对象编程(OOP)特性的核心之一。接收器的作用是将方法绑定到某个类型的实例(值或者指针),让该类型的实例能够调用方法。

1. 什么是接收器?

接收器是方法的一部分,它标识了方法所属的类型(即哪个类型能够调用这个方法)。接收器出现在方法的参数列表的第一个位置,在语法上类似于函数的参数,但它表示的是方法的调用对象。

接收器的作用是使得方法与特定类型的对象(实例)关联,类似于其他编程语言中的类(class)中的成员函数(member function)或实例方法(instance method)。

2. 接收器的位置与语法

接收器的声明位于方法的参数列表的前面,格式如下:

func (receiverType ReceiverType) MethodName(parameters) returnType {
    // 方法体
}
  • receiverType:表示接收器的类型,指定该方法所操作的数据类型。
  • ReceiverType:是接收器的名称,通常是类型的一个实例,但也可以是该类型的指针。
  • MethodName:方法的名称。
  • parameters:方法的其他参数。
  • returnType:方法的返回类型。

3. 接收器的类型

Go 支持两种类型的接收器:值接收器指针接收器。这决定了方法中对接收器的修改是否会影响原始对象。

3.1 值接收器(Value Receiver)

值接收器是在方法调用时,复制接收器对象的副本。当你在方法内对接收器对象进行操作时,修改不会影响到原始对象。通常当你不打算修改接收器对象的状态时,使用值接收器。

示例:

package main

import "fmt"

type Rectangle struct {
    width, height int
}

// 值接收器方法
func (r Rectangle) Area() int {
    return r.width * r.height
}

func main() {
    rect := Rectangle{width: 10, height: 5}
    fmt.Println("Area of rectangle:", rect.Area())  // 输出:Area of rectangle: 50
}

在这个例子中,Area() 方法的接收器是 Rectangle 的值接收器,因此 Area() 方法内部对 r 的修改不会影响原始的 rect

3.2 指针接收器(Pointer Receiver)

指针接收器使用指向接收器类型的指针。在方法调用时,接收器参数是该对象的地址。指针接收器允许在方法内部修改接收器对象的状态。

示例:

package main

import "fmt"

type Rectangle struct {
    width, height int
}

// 指针接收器方法
func (r *Rectangle) SetWidth(width int) {
    r.width = width
}

func main() {
    rect := Rectangle{width: 10, height: 5}
    rect.SetWidth(20)
    fmt.Println("Updated rectangle:", rect)  // 输出:Updated rectangle: {20 5}
}

在这个例子中,SetWidth() 方法的接收器是指针接收器,因此可以通过该方法修改 rect 对象的 width 属性。

4. 为什么选择指针接收器或值接收器?

  • 值接收器:适用于方法不需要修改接收器的情况下,或者接收器类型是小型类型(如基础类型、结构体等),复制副本开销小。Go 的值接收器对于避免对原始对象的影响非常有效。

  • 指针接收器:适用于需要修改接收器对象的情况下,或者接收器类型较大,避免每次复制带来的性能问题。

5. 接收器的命名

接收器的命名可以是任何合适的名字,Go 语言对命名没有特别要求。通常采用短小的名字,尤其是单字符的变量名,以符合 Go 的编码规范。常见的接收器命名包括:

  • r:通常用于 Rectangle 类型的接收器。
  • s:通常用于 String 类型的接收器。
  • t:常用于 Time 类型的接收器。

不过,命名接收器时没有强制规则,可以根据需求进行命名。

6. 接收器与方法的绑定

接收器可以绑定到某个类型或类型的指针。当你调用方法时,Go 会自动根据需要将接收器转换为相应的值或指针。你可以将指针类型的变量传递给值接收器,反之亦然,只要类型一致。

示例:自动转换
package main

import "fmt"

type Rectangle struct {
    width, height int
}

// 指针接收器
func (r *Rectangle) SetWidth(width int) {
    r.width = width
}

func main() {
    rect := Rectangle{width: 10, height: 5}
    rect.SetWidth(20)  // Go 会自动将 rect 的值转换为指针
    fmt.Println("Updated rectangle:", rect)  // 输出:Updated rectangle: {20 5}
}

在上述代码中,rectRectangle 的值类型,但 SetWidth() 方法接受指针接收器,Go 会自动将 rect 的地址传递给方法。

7. 接收器的使用场景

  • 值接收器:当方法不修改接收器的值,并且接收器的复制开销较小时,使用值接收器。
  • 指针接收器:当方法需要修改接收器的值,或者接收器对象较大时,使用指针接收器。

8. 接收器的限制

  1. 方法与接口:当一个类型的方法使用了值接收器时,该类型才能实现接口;而当类型的方法使用指针接收器时,只有类型的指针才能实现该接口。
  2. 传递给方法的参数:如果方法定义了指针接收器,你必须传递指向该类型的指针给方法,反之亦然。

总结

Go 语言的接收器(Receiver)是绑定方法到特定类型的机制,分为值接收器和指针接收器两种类型,决定了方法如何访问和修改接收器对象的状态。选择适当的接收器类型可以优化代码的性能,并且正确地使用接收器能有效管理对象的状态和行为。

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

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

相关文章

操作系统大题整理

专题一 程序代码题:程序设计与分析,主要考的是线程,多线程的并发? 大题第一问(1)操作系统的结构有哪几种常用的结构? 宏内核:宏内核是将操作系统的主要功能模块都集中在内核的一种结…

SQL编程语言

第一章 1. 数据库是长期储存在计算机内,由专门的数据管理软件(数据库管理系统),进行统一组织和管理控制的大量数据的集合。 2.数据库的基本特点不包括可以快速检索。 3. 数据管理技术的发展经历了:人工管理阶段、文件系统阶段、数据库系统阶…

【跨域问题】

跨域问题 官方概念: 当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域本质来说,是前端请求给到后端时候,请求头里面,有一个 Origin ,会带上 协议域名端口号等;后端接受到请求&…

Linux(CentOS7)安装JDK和Maven

文章目录 CentOS软件安装方式JDK安装Maven安装 CentOS软件安装方式 安装方式特点二进制发布包安装软件已经针对具体平台编译打包发布,只要解压,修改配置即可。例如tomcatrpm(redhat package manager)安装软件已经按照redhat的包管理规范进行打包&#x…

RabbitMQ 可观测性最佳实践

RabbitMQ 简介 RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写,支持多种客户端。它通过使用交换机(Exchanges)、队列(Queues)和绑定(Bindings)来路由消息&#xff…

Github Copilot学习笔记

(一)Prompt Engineering 利用AI工具生成prompt设计好的prompt结构使用MarkDown语法,按Role, Skills, Constrains, Background, Requirements和Demo这几个维度描述需求。然后收输入提示词:作为 [Role], 拥有 [Skills], 严格遵守 […

单片机-定时器中断

1、相关知识 振荡周期1/12us; //振荡周期又称 S周期或时钟周期(晶振周期或外加振荡周期)。 状态周期1/6us; 机器周期1us; 指令周期1~4us; ①51单片机有两组定时器/计数器,因为既可以定时,又可以计数,故称之为定时器…

高比例压缩:Linux 中的压缩命令与技巧

文章目录 高比例压缩:Linux 中的压缩命令与技巧1. 压缩格式的选择2. gzip 命令示例:压缩文件示例:解压文件 3. bzip2 命令示例:压缩文件示例:解压文件 4. xz 命令示例:压缩文件示例:解压文件 5.…

【ArcGIS Pro二次开发实例教程】(1):图层的前置、后置

一、简介 此工具要实现的功能是:将内容框中当前选定的图层移到最顶层或最底层。 主要技术要点包括: 1、Config.daml文件设置(UI设置) 2、按钮的图片和位置设置 3、当前选定图层的获取 4、图层在内容列表中位置的获取和移动 …

Sprint Boot教程之五十:Spring Boot JpaRepository 示例

Spring Boot JpaRepository 示例 Spring Boot建立在 Spring 之上,包含 Spring 的所有功能。由于其快速的生产就绪环境,使开发人员能够直接专注于逻辑,而不必费力配置和设置,因此如今它正成为开发人员的最爱。Spring Boot 是一个基…

ESP32 IDF VScode出现头文件“无法打开 源 文件 ”,并有红色下划线警告

问题背景: ESP32 IDF VScode出现头文件“无法打开 源 文件 ”,并有红色下划线警告: 解决办法: 在工程里面的.vscode文件夹下,检查是否存在c_cpp_properties.json文件,如果没有可以手动创建添加。如图…

【Shell脚本】Docker构建Java项目,并自动停止原镜像容器,发布新版本

本文简述 经常使用docker部署SpringBoot 项目,因为自己的服务器小且项目简单,因此没有使用自动化部署。每次将jar包传到服务器后,需要手动构建,然后停止原有容器,并使用新的镜像启动,介于AI时代越来越懒的…

关于ssh-server在windows系统中进行部署及通过mobaxterm中ssh隧道技术实现不同网段之间进行网络通讯的问题

问题1.windows系统部署ssh-server 在安装部署过程中参考先行者就可实现部署。我使用的作者百度云安装包。 记录一下操作步骤: 1.在搜索中打开power shell命令行,将文件夹复制到C:\Program Files,切换到OpenSSH-Win64,执行如下安装…

写了个小工具,绿色/C#/Url/Base64/Encode/Decode

写这个小工具的动机是什么呢? 虽然很多在线工具也非常地方便,但经常在抓包的时候需要操作相关的转码工作,但你开着抓包工具访问网页有时候又非常地不方便。这时候就想到如果有一款本地的工具软件,就非常地耐斯。 这种工具也不是…

【优选算法】Binary-Blade:二分查找的算法刃(下)

文章目录 1.山脉数组的峰顶索引2.寻找峰值3.寻找旋转排序数组中的最小值4.点名希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的动力! 本篇接上一篇二分查找,主要通过部分题目熟悉二分查找的进阶使用,重点强调二段性,…

【Ubuntu22.04】VMware虚拟机硬盘扩容

1.首先打开虚拟机设置 2.根据需要对硬盘扩展 这边提示我们还需要进入虚拟机在内部分区 3.安装界面化磁盘管理工具 # 安装 sudo apt install gparted# 启动 sudo gparted调整硬盘大小 调整的时候会提示我们硬盘是只读的,因此还要进行操作 新建终端重新挂载文件系…

无网络时自动切换备用网络环境

目录 背景目标为什么需要做自动网络切换网络切换手段 网络环境实现思路和代码部署脚本开机自动执行附录连接两个网络时的路由问题 背景 目标 学校实验室有两个网络环境,我电脑使用网线连接稳定但低速的网络A,使用WiFi连接高速但不稳定的网络B。因此&am…

设计模式 行为型 策略模式(Strategy Pattern)与 常见技术框架应用 解析

策略模式(Strategy Pattern)核心思想是将算法的实现从使用该算法的类中分离出来,作为独立的对象,通过接口来定义算法家族,这样就可以很容易地改变或扩展算法。通过这种方式,可以避免在客户端代码中使用大量…

Unity 热更新基础知识

文章目录 1.一些名词2.三种编译方式3.Unity 两种脚本后端3.1 Mono3.2 IL2CPP3.3 对比 1.一些名词 IL(Intermediate Language):中间语言(类似于汇编代码)CIL(Common Intermediate Language)&…

C++感受15-Hello STL 泛型启蒙

生鱼片和STL的关系,你听过吗?泛型编程和面向对象编程,它们打架吗?行为泛型和数据泛型,各自的目的是? 0 楔 俄罗斯生鱼片,号称俄罗斯版的中国烤鸭,闻名于世。其鱼肉,源于…