Golang结构体使用指针和值的传递问题

本文将详细讨论在Go语言中使用指针和值传递结构体的问题,以及他们的不同和需要注意的问题;

在开始前你需要先掌握结构体的定义、声明以及使用方法;

我们先来看一段代码:

package main

type T struct{
	Value 		int
}

func main(){
	myT := T{Value:666}

	change(myT)

	println(myT.Value)

}
func change(t T){
	t.Value = 999
}

程序的输出是 666 ,因为这种方法传递的是值一个副本,在change() 函数中,你实际上修改的是副本的值;

修改程序,让它使用指针进行传递:

package main

type T struct{
	Value 		int
}

func main(){
	myT := T{Value:666}

	change(&myT)

	println(myT.Value)

}
func change(t *T){
	t.Value = 999
}

这段程序使用了&取地址操作符来获取结构体的地址,而change()函数期望一个T结构体的地址类型 *T,这里*T的意思是指向类型T值得指针;

程序运行输出 999;

但我们需要注意的是,实际上这里传递的依然是一个副本,只不过这个副本是一个地址,它指向原来的值;

所以,你可以修改 t.Value的值,但你无法修改 t;

package main

type T struct{
	Value 		int
}

func main(){
	myT := T{Value:666}

	change(&myT)

	println(myT.Value)

}
func change(t *T){
	t = &T{Value:999}
}

这段代码输出666;

那么,应该如何选择传递方式呢?

很明显,复制一个指针比复制一个结构的消耗要小的多;如果我们的结构非常复杂和庞大,那么复制结构会是一个很消耗性能的操作,在进行大量这样的操作时你的感觉会非常明显;

而使用指针则可避免这个问题;

当你的函数本意是改变原始数据时,那么肯定用指针转递;

当你的结构非常大时,比如包含庞大的切片、map时,也需要用指针转递;

但是如果你的结构体非常小,且不打算修改结构体内容,那么应该考虑使用值传递;

因为你不能保证程序没有bug导致误修改;且在某些多任务环境下,你需要为指针操作添加额外的锁操作,这样有些得不偿失。

原创内容,如需转载,请注明出处;

本文地址: https://www.perfcode.com/p/golang-struct-pointer.html

分类: 计算机技术
推荐阅读:
Qt在Windows11下的视觉效果 作者更新到Windows11了,来看看Qt在Windows11下的视觉效果;变化比较明显的是窗口,PushButton控件和输入框控件;
Golang中关键字fallthrough在switch语句里的用法 和C语言不同,在Go语言里的 switch 语句中,是不需要使用 break 来退出一个case的。也就是说,case执行完成后,是不会继续向下匹配的。
PySide6模块的导入和使用 Qt拥有众多的模块帮助你构建应用程序,例如QtCore,QtGui,QtNetwork,QtOpenGL,QtQuick,QtQml,QtWidgets等等;本文将讲解PySide6常用模块的功能以及在Python中的导入和使用方法;
C语言memmove()函数:在内存中移动一段数据 memmove()是C语言标准库中的一个函数,用于在内存中移动一段数据,其原理是通过复制数据到临时缓冲区来实现移动;
Python实现猜拳小游戏 曾经给一个小屁孩做的作业,放出来分享。。。实现思路: 定义一个玩家类;实现获取用户的输入。 定义一个机器人类;实现机器人的输入。 定义一个裁判类;裁判判断双方胜负。 定义游戏桌面;实现游戏的启动和管理。
Python bytes()函数 bytes 是 Python 中的一个内置类,用于表示二进制数据。bytes 对象是不可变的,即一旦创建,就不能修改其中的元素。由于二进制数据通常是不可变的,因此 bytes 类型广泛应用于文件、网络通信等场合。