内容目录
概述
在大多数编程语言中,函数参数的传递方式可以分为两种类型:值传递和引用传递。
比如,在Java中,对象的引用是通过’引用传递’,而基本数据类型则是通过’值传递’。在Python中,变量总是通过引用传递,不过由于其对象模型的不可变性,表现可能会像值传递。而在Go语言中,可以通过指针显式地使用引用传递。
值传递
在值传递中,函数收到参数的副本。这意味着,原始数据是安全的,不会受到函数中操作的影响,因为函数操作的仅仅是副本。
这就像给朋友发照片:你发送的是图片的副本,你的原图不会受到影响,即使朋友对照片进行了编辑。
举个例子来看值传递:
package main
import "fmt"
func modifyValue(val int) {
// 修改的是副本
val *= 2
}
func main() {
initial := 10
// 发送一个原始值的副本
modifyValue(initial)
// initial保持不变
fmt.Println("initial after modifyValue:", initial)
}
运行截图如下:
指针传递(通过指针)
指针传递,是把参数的内存地址传给函数,调用函数时会将这个内存地址复制。这样,函数就能直接修改存在于该地址的原始数据。
这就像是给朋友家钥匙,让他们直接进入你家修改东西。他们的操作会直接反应在你的家(原始数据)上。
来看一个指针传递的例子:
package main
import "fmt"
func modifyPointer(ptr *int) {
// 直接修改原始值
*ptr *= 2
}
func main() {
initial := 10
// 发送内存地址
modifyPointer(&initial)
// initial被修改了
fmt.Println("initial after modifyPointer:", initial)
}
运行截图如下:
总结指针传递的优势
来点需要背诵的知识吧。
- 修改原始数据: 通过指针传递,可以直接对原始数据进行操作(传入传出参数就用指针)。
- 节省内存开销: 大型的数据结构在值传递中会产生巨大的内存拷贝,但指针仅传递地址,非常高效。
- 共享数据: 指针允许多个函数操作同一数据源,实现数据共享。
- 灵活性: 可以处理任何类型的数据,只要是一致的接口或类型。
- 性能优化: 在性能要求高的场景下,指针避免数据拷贝,提升效率。
节省内存单独说下
先来个大型的数据结构的例子:
package main
import "fmt"
// 大型结构
type BigStruct struct {
// 10000个整数的数组
Data [10000]int
}
// 通过值传递,复制整个结构体
func modifyBigStruct(bs BigStruct) {
// 只修改副本的第一个元素
bs.Data[0] = 10
}
func main() {
// 创建并初始化一个庞大的结构体实例
big := BigStruct{}
// 值传递
modifyBigStruct(big)
// 原结构体保持不变
fmt.Println("First element after modifyBigStruct:", big.Data[0])
}
接下来我们来一个指针传递:
package main
import "fmt"
// 大型结构
type BigStruct struct {
Data [10000]int
}
// 通过指针传递,直接操作原结构体
func modifyBigStructPtr(bs *BigStruct) {
// 修改原结构体的第一个元素
bs.Data[0] = 10
}
func main() {
big := BigStruct{}
// 引用传递(指针传递)
modifyBigStructPtr(&big)
// 原结构体被修改
fmt.Println("First element after modifyBigStructPtr:", big.Data[0])
}
I am extremely impressed together with your writing talents as neatly as
with the structure on your weblog. Is this a paid theme or did you modify
it yourself? Either way keep up the excellent quality writing, it is uncommon to look a great blog like this one today..
Hi Randall, thank you for your comment. I used the free version of the theme.