扫码订阅《 》或入驻星球,即可阅读文章!

GOLANG ROADMAP

阅读模式

  • 沉浸
  • 自动
  • 日常
首页
Go学习
  • Go学院

    • Go小课
    • Go小考
    • Go实战
    • 精品课
  • Go宝典

    • 在线宝典
    • B站精选
    • 推荐图书
    • 精品博文
  • Go开源

    • Go仓库
    • Go月刊
  • Go下载

    • 视频资源
    • 文档资源
Go求职
  • 求职服务

    • 内推互助
    • 求职助力
  • 求职刷题

    • 企业题库
    • 面试宝典
    • 求职面经
Go友会
  • 城市
  • 校园
推广返利 🤑
实验区
  • Go周边
消息
更多
  • 用户中心

    • 我的信息
    • 推广返利
  • 玩转星球

    • 星球介绍
    • 角色体系
    • 星主权益
  • 支持与服务

    • 联系星主
    • 成长记录
    • 常见问题
    • 吐槽专区
  • 合作交流

    • 渠道合作
    • 课程入驻
    • 友情链接
author-avatar

GOLANG ROADMAP


首页
Go学习
  • Go学院

    • Go小课
    • Go小考
    • Go实战
    • 精品课
  • Go宝典

    • 在线宝典
    • B站精选
    • 推荐图书
    • 精品博文
  • Go开源

    • Go仓库
    • Go月刊
  • Go下载

    • 视频资源
    • 文档资源
Go求职
  • 求职服务

    • 内推互助
    • 求职助力
  • 求职刷题

    • 企业题库
    • 面试宝典
    • 求职面经
Go友会
  • 城市
  • 校园
推广返利 🤑
实验区
  • Go周边
消息
更多
  • 用户中心

    • 我的信息
    • 推广返利
  • 玩转星球

    • 星球介绍
    • 角色体系
    • 星主权益
  • 支持与服务

    • 联系星主
    • 成长记录
    • 常见问题
    • 吐槽专区
  • 合作交流

    • 渠道合作
    • 课程入驻
    • 友情链接
  • 课程介绍

    • 《Go语言面试题精讲》
  • Go基础

    • 1.Go 程序的基本结构?
    • 2. Go 有哪些关键字?
    • 3. Go 有哪些数据类型?
    • 4. Go 方法与函数的区别?
    • 5.Go 方法值接收者和指针接收者的区别?
    • 6. Go 函数返回局部变量的指针是否安全?
    • 7.Go 函数参数传递到底是值传递还是引用传递?
    • 8.Go defer关键字的实现原理?
    • 9.Go 内置函数make和new的区别?
  • Slice

  • Map

  • Channel

  • Mutex

  • Goroutine

  • 调度模型

  • 内存管理

  • 并发编程

扫码订阅《 》或入驻星球,即可阅读文章!

5.Go 方法值接收者和指针接收者的区别?


caspar
【点击观看视频】Go 方法值接收者和指针接收者的区别?

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

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

package main

import "fmt"

type Person struct {
	age int
}

// 如果实现了接收者是指针类型的方法,会隐含地也实现了接收者是值类型的IncrAge1方法。
// 会修改age的值
func (p *Person) IncrAge1() {
	p.age += 1
}

// 如果实现了接收者是值类型的方法,会隐含地也实现了接收者是指针类型的IncrAge2方法。
// 不会修改age的值
func (p Person) IncrAge2() {
	p.age += 1
}

// 如果实现了接收者是值类型的方法,会隐含地也实现了接收者是指针类型的GetAge方法。
func (p Person) GetAge() int {
	return p.age
}

func main() {
	// p1 是值类型
	p := Person{age: 10}

	// 值类型 调用接收者是指针类型的方法
	p.IncrAge1()
	fmt.Println(p.GetAge())
	// 值类型 调用接收者是值类型的方法
	p.IncrAge2()
	fmt.Println(p.GetAge())

	// ----------------------

	// p2 是指针类型
	p2 := &Person{age: 20}

	// 指针类型 调用接收者是指针类型的方法
	p2.IncrAge1()
	fmt.Println(p2.GetAge())
	// 指针类型 调用接收者是值类型的方法
	p2.IncrAge2()
	fmt.Println(p2.GetAge())
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

上述代码中:

实现了接收者是指针类型的 IncrAge1 函数,不管调用者是值类型还是指针类型,都可以调用IncrAge1方法,并且它的 age 值都改变了。

实现了接收者是指针类型的 IncrAge2 函数,不管调用者是值类型还是指针类型,都可以调用IncrAge2方法,并且它的 age 值都没有被改变。

通常我们使用指针类型作为方法的接收者的理由:

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