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

分类: 计算机技术
推荐阅读:
MySQL ADDDATE() 函数 ADDDATE()函数用于将一个时间值增加到一个日期当中;通俗的讲,就是可以通过这个函数将一个日期增加多少天;
Rust while 条件循环 Rust 内置了while循环结构;当条件为真时,执行循环,当条件不为真时,停止循环;
Python tuple元组 tuple(元组)类似于列表,但元组当中的项不能被修改。
Updating crates.io index 出现错误解决方法 在向Rust项目添加依赖后尝试运行或编译,cargo管理工具会尝试更新crates.io index,当出现git配置错误可能会出现类似以下的错误:
WHOIS协议Python和Golang的实现 WHOIS协议是一个非常简单的Internet信息查询协议;在RFC812文档中有定义,先向服务器的TCP 43端口建立一个连接,发送要查询的域名关键字并以回车换行结尾,然后接收服务器返回信息,服务器输出完毕后会立即断开连接。
Python pow()函数 pow() 函数是 Python 内置函数之一,用于计算一个数的幂。它接受两个参数,第一个参数为底数,第二个参数为指数,如果提供第三个参数,则表示对结果取模。