在Go中什么时候使用指针?

简介: 在Go中什么时候使用指针?

1 在方法中使用指针

什么是receiver?

func (t T) method_name(t T){}

这里面的T就是receiver

  • 使用receiver作为方法参数
func main() {
   r := receiver{Name: "zs"}
   fmt.Println(r)
   r.methodA()
   fmt.Println(r)
}
type receiver struct {
   Id   int
   Name string
   Age  int
}
func (receiver receiver) methodA() {
   receiver.Name = "ls"
}
func (receiver *receiver) methodB() {
   receiver.Name = "ls"
}

结果:

{0 zs 0}

{0 zs 0}

  • 使用*receiver作为方法参数
func main() {
   r := receiver{Name: "zs"}
   fmt.Println(r)
   r.methodB()
   fmt.Println(r)
}
type receiver struct {
   Id   int
   Name string
   Age  int
}
func (receiver receiver) methodA() {
   receiver.Name = "ls"
}
func (receiver *receiver) methodB() {
   receiver.Name = "ls"
}

结果:

{0 zs 0}

{0 ls 0}

2 在结构体中使用指针

  • 方式一
func main() {
   student := Student{Map: map[string]int{"S": 0}, ReceiverA: receiver{Name: "A"}, ReceiverB: &receiver{Name: "B"}}
   fmt.Println(student, *student.ReceiverB)
   student.updateA()
   fmt.Println(student, *student.ReceiverB)
}
type receiver struct {
   Id   int
   Name string
   Age  int
}
type Student struct {
   No        int
   Map       map[string]int
   ReceiverA receiver
   ReceiverB *receiver
}
func (stu Student) updateA() {
   stu.Map["a"] = 1
   stu.ReceiverA = receiver{Name: "ww"}
   stu.ReceiverB = &receiver{Name: "ww"}
}
func (stu *Student) updateB() {
   stu.Map["b"] = 2
   stu.ReceiverA = receiver{Name: "ww"}
   stu.ReceiverB = &receiver{Name: "ww"}
}

结果:

{0 map[S:0] {0 A 0} 0xc0000b4000} {0 B 0}

{0 map[S:0 a:1] {0 A 0} 0xc0000b4000} {0 B 0}

  • 方式二
func main() {
   student := Student{Map: map[string]int{"S": 0}, ReceiverA: receiver{Name: "A"}, ReceiverB: &receiver{Name: "B"}}
   fmt.Println(student, *student.ReceiverB)
   student.updateA()
   fmt.Println(student, *student.ReceiverB)
}
type receiver struct {
   Id   int
   Name string
   Age  int
}
type Student struct {
   No        int
   Map       map[string]int
   ReceiverA receiver
   ReceiverB *receiver
}
func (stu Student) updateA() {
   stu.Map["a"] = 1
   stu.ReceiverA = receiver{Name: "ww"}
   stu.ReceiverB = &receiver{Name: "ww"}
}
func (stu *Student) updateB() {
   stu.Map["b"] = 2
   stu.ReceiverA = receiver{Name: "ww"}
   stu.ReceiverB = &receiver{Name: "ww"}
}

结果:

{0 map[S:0] {0 A 0} 0xc0000b4000} {0 B 0}

{0 map[S:0 b:2] {0 ww 0} 0xc0000b4060} {0 ww 0}

3 什么时候使用指针

一个函数何时该用指针类型做receiver对初学者而言一直是个头疼的问题。下面是列举了一些常用的判断指导。

  • 如果receiver是mapfunc或者chan,不要使用指针
  • 如果receiver是slice并且该函数并不会修改此slice,不要使用指针
  • 如果该函数会修改receiver,此时一定要用指针
  • 如果receiver是struct并且包含互斥类型sync.Mutex,或者是类似的同步变量,receiver必须是指针,这样可以避免对象拷贝
  • 如果receiver是较大的struct或者array,使用指针则更加高效。多大才算大?假设struct内所有成员都要作为函数变量传进去,如果觉得这时数据太多,就是struct太大
  • 如果receiver是structarray或者slice,并且其中某个element指向了某个可变量,则这个时候receiver选指针会使代码的意图更加明显
  • 如果receiver使较小的struct或者array,并且其变量都是些不变量、常量,例如time.Time,value receiver更加适合,因为value receiver可以减少需要回收的垃圾量。
  • 最后,如果不确定用哪个,使用指针类的receiver

参考文章:

https://zhuanlan.zhihu.com/p/395747448

相关文章
|
21天前
|
存储 Go iOS开发
掌握Go语言:探索Go语言指针,解锁高效内存操作与动态数据结构的奥秘(19)
掌握Go语言:探索Go语言指针,解锁高效内存操作与动态数据结构的奥秘(19)
|
5天前
|
存储 Go
Go 语言指针
Go 语言指针
11 0
|
21天前
|
Java Go
一文带你速通go语言指针
Go语言指针入门指南:简述指针用于提升效率,通过地址操作变量。文章作者sharkChili是Java/CSDN专家,维护Java Guide项目。文中介绍指针声明、取值,展示如何通过指针修改变量值及在函数中的应用。通过实例解析如何使用指针优化函数,以实现对原变量的直接修改。作者还邀请读者加入交流群深入探讨,并鼓励关注其公众号“写代码的SharkChili”。
24 0
|
21天前
|
Java Go 区块链
【Go语言专栏】Go语言中的指针与内存管理
【4月更文挑战第30天】Go语言,由Google开发,是一种静态强类型、编译型、并发型语言,具有垃圾回收功能,常用于云计算、微服务、区块链等领域。本文聚焦Go中的指针和内存管理。指针表示变量内存地址,可用于直接访问和修改变量,如示例代码所示。指针运算有限制,仅支持相同类型变量和数组元素访问。内存管理由Go运行时的垃圾回收机制处理,自动回收无引用对象,简化管理但引入性能开销。可通过`runtime.GC()`手动触发垃圾回收。
|
21天前
|
Java Go
Golang深入浅出之-Go语言指针面试必知:理解与使用指针
【4月更文挑战第21天】Go语言中的指针允许直接操作内存,常用于高效数据共享和传递。本文介绍了指针的基础知识,如声明、初始化和解引用,以及作为函数参数使用。此外,讨论了`new()`与`make()`的区别和内存逃逸分析。在结构体上下文中,指针用于减少复制开销和直接修改对象。理解指针与内存管理、结构体的关系及常见易错点,对于面试和编写高性能Go代码至关重要。
22 2
|
21天前
|
存储 安全 Java
Go语言学习10-指针类型
【4月更文挑战第11天】本篇 Huazie 向大家介绍 Go语言的指针类型
22 2
Go语言学习10-指针类型
|
21天前
|
存储 编译器 Go
go语言第五章(指针)
go语言第五章(指针)
27 0
|
21天前
|
存储 JSON Java
云原生系列Go语言篇-指针
我们已学习过变量和函数,下面来快速了解下指针的语法。然后我们通过将Go中的指针与其它语言中的类进行对比来讲清指针的原理。我们还会学习如何以及何时使用指针、Go中如何分配内存以及正确使用指针及值是如何使Go程序变得更快速、更高效的。
88 0
|
6月前
|
存储 Cloud Native 安全
GO 中的指针?
GO 中的指针?
|
7月前
|
存储 安全 编译器
深入解析Go非类型安全指针:技术全解与最佳实践2
深入解析Go非类型安全指针:技术全解与最佳实践2
211 0