首页 > 其他分享 >golang 值接收者和指针接收者

golang 值接收者和指针接收者

时间:2024-07-22 16:20:08浏览次数:15  
标签:接收者 golang sleep 类型 方法 eat 指针

代码示例

先看个代码:

package main

import (
	"fmt"
	"testing"
)

func TestValRecv(t *testing.T) {
	var a animal = dog{"五红犬"}
	a.eat()
	a.sleep()

	var b animal = &dog{"五黑犬"}
	b.eat()
	b.sleep()
}

func TestPtrRecv(t *testing.T) {
	var a animal = &cat{"蓝猫"}
	a.eat()
	a.sleep()

	var b animal = cat{"胖橘"} // sleep only a ptr recv,出错
	b.eat()
	b.sleep()
}

type animal interface {
	eat()
	sleep()
}

type dog struct {
	name string
}

func (d dog) eat()  {
	fmt.Printf("%s eat...\n", d.name)
}

func (d dog) sleep()  {
	fmt.Printf("%s sleep...\n", d.name)
}

type cat struct {
	name string
}

func (d cat) eat()  {
	fmt.Printf("%s eat...\n", d.name)
}

func (d *cat) sleep()  {
	fmt.Printf("%s sleep...\n", d.name)
}

先说结论:

  • 值接收者,默认实现了值接收和指针接收方法,源对象的一个复制或者拷贝
  • 指针接收,只实现指针接收,重点是修改原对象

所以上面 cat 一个是 eat() 值接收方法,实现了二者,而 sleep() 指针接收,只实现了指针接收,未完全实现接口 animal 的两个方法。

如果不涉及接口,二者都可以,但涉及到接口涉及具体实现问题。

对于接口

结论:
实现了接收者是值类型的接口方法,相当于自动实现了接收者是指针类型的方法;
实现了接收者是指针类型的接口方法,不会自动生成对应接收者是值类型的方法。

简单的解释

接收者是指针类型的方法,很可能在方法中会对接收者的属性进行更改操作,从而影响接收者;而对于接收者是值类型的方法,在方法中不会对接收者本身产生影响。
所以,当实现了一个接收者是值类型的方法,就可以自动生成一个接收者是对应指针类型的方法,因为两者都不会影响接收者。但是,当实现了一个接收者是指针类型的方法,如果此时自动生成一个接收者是值类型的方法,原
本期望对接收者的改变(通过指针实现),现在无法实现,因为值类型会产生一个拷贝,不会真正影响调用者。

两者分别在何时使用

如果方法的接收者是值类型,无论调用者是对象还是对象指针,修改的都是对象的副本,不影响调用者;如果方法的接收者是指针类型,则调用者修改的是指针指向的对象本身。

使用指针作为方法的接收者的理由:
方法能够修改接收者指向的值。避免在每次调用方法时复制该值,在值的类型为大型结构体时,这样做会更加高效。

使用值接收者还是指针接收者,不是由该方法是否修改了调用者(也就是接收者)来决定,而是应该基于该类型的本质。

如果类型具备“原始的本质”,也就是说它的成员都是由 Go 语言里内置的原始类型,如字符串,整型值等,那就定义值接收者类型的方法。像内置的引用类型,如 slice,map,interface,channel,这些类型比较特殊,声明他们的时候,实际上是创建了一个 header, 对于他们也是直接定义值接收者类型的方法。这样,调用函数时,是直接 copy 了这些类型的 header,而 header 本身就是为复制设计的。

如果类型具备非原始的本质,不能被安全地复制,这种类型总是应该被共享,那就定义指针接收者的方法。比如 go 源码里的文件结构体(struct File)就不应该被复制,应该只有一份实体。

参考:

标签:接收者,golang,sleep,类型,方法,eat,指针
From: https://www.cnblogs.com/davis12/p/18316267

相关文章

  • 深入浅出C语言指针(基础篇)
    目录引言一、认识指针指针是什么? 二、指针变量和地址1.取地址操作符2.指针变量3.解引用操作符 4.指针变量的大小 三、指针和指针类型1.指针的类型2.指针+-整数3.指针的解引用四、const修饰指针变量 1.const修饰指向的数据2.const修饰指针本身3.const同......
  • Golang:bytes 格式和解析数字字节值(10K、2M、3G等)
    Golang:bytes格式和解析数字字节值(10K、2M、3G等)原创吃个大西瓜CodingBigTree 2024年06月10日08:01北京图片 bytes格式和解析数字字节值(10K、2M、3G等) 文档 https://github.com/labstack/gommon/tree/master/bytes安装 gogetgithub.com/labstack/go......
  • c++ 引用和指针
      c++引用和指针在C++中,引用和指针是两个非常重要的概念,它们有一些相似之处也有一些不同之处。相似之处:引用和指针都可以指向一个对象。引用一旦被初始化指向一个对象后,就不能再指向其他对象,而指针可以在任何时候指向其他对象。不同之处:引用在......
  • 深入探究 Golang 反射:功能与原理及应用
    Hi亲爱的朋友们,我是k哥。今天,咱们来一同探讨下Golang反射。Go出于通用性的考量,提供了反射这一功能。借助反射功能,我们可以实现通用性更强的函数,传入任意的参数,在函数内通过反射动态调用参数对象的方法并访问它的属性。举例来说,下面的bridge接口为了支持灵活调用任意函数,在......
  • day4 链表-模拟与快慢指针
    目录任务24.两两交换链表中的节点思路19.删除链表的倒数第N个节点思路面试题02.07.链表相交思路142.环形链表II思路总结任务24.两两交换链表中的节点给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节......
  • C语言指针详解(进阶)
    二、指针的进阶    本章重点:            1.字符指针        2.数组指针        3.指针数组        4.数组传参和指针传参        5.函数指针        6.函数指针数组    ......
  • 深入浅出_指针
    指针指针基本介绍变量在内存中的存储如图中右侧图形表示计算机内存(memory),图形中每一个长条表示一个字节(byte),每一个字节存在对应的一个地址,如左侧0、201、202...209所标注对于典型的现代计算机,1个int类型变量由4个字节表示,1个char类型变量由1个字节表示,1个float类型变量由......
  • C++ 智能指针
    一、为什么需要智能指针看如下代码有什么问题:intdiv(){ inta,b; cin>>a>>b; if(b==0) throwinvalid_argument("除0错误"); returna/b;}voidFunc(){ //1、如果p1这里new抛异常会如何? //2、如果p2这里new抛异常会如何? //3、如果div调用这里又......
  • 15 指针 · 其三 · 进阶
    目录一、字符指针变量(一)字符指针与字符串数组区别二、数组指针变量(一)数组指针介绍(二)数组指针初始化(三)数组指针的使用三、二维数组传参的本质四、函数指针变量(一)函数指针介绍1、函数的地址2、函数指针的写法(二)函数指针的使用(三)两段有趣的代码(四)typedef五、函数......
  • C/C++ 《二级指针浅拷贝》
    背景A对象内部属性a属于int,动态分配内存回收,析构函数deleteA**aptr=newA[10]申请10个空间长度的A*类型测试浅拷贝测试代码#include<iostream>usingnamespacestd;classA{public:int*a;A(inti){//构造函数a=newint(i);}~A(......