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

分类: 计算机技术
推荐阅读:
Implementation of the USB 2.0 controller not found!解决方案 你可能在使用VirtualBox启动虚拟机系统时碰到“不能为虚拟电脑打开一个新的任务”的错误提示,并提示 Implementation of the USB 2.0 controller not found!
requests定制HTTP请求头 如果你想为HTTP请求添加或修改头部信息,只需给 headers参数传递一个字典。
Python memoryview()函数 memoryview() 函数是一个内置函数,它返回一个memoryview对象,该对象可以用于在 Python 中访问二进制数据。
Microsoft Office 禁用自动更新方法 近日,作者发现 Microsoft Office会偷偷摸摸的自动安装更新,这点是我无法忍受的,因为像这样的大型软件,随随便便更新以下就是几百兆的更新包,不仅占用网络资源,而且对我心爱的固态硬盘极为不利,而且这些软件更新推送很频繁;
QtSpim: Attempt to execute non-instruction at 0x00400030 错误解决方法 使用QtSpim运行MIPS32汇编代码时提示Attempt to execute non-instruction at 0x00400030 错误表示你的程序没有正确退出;
Python complex()函数 在Python中,complex()函数用于创建一个复数对象,它可以接受两个参数,表示复数的实部和虚部,也可以只传入一个参数,此时表示复数的实部为该参数,虚部为0。