文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
传值与传指针
传一个参数值到被调用函数里面时,实际上是传了这个值的一份 copy,当在被调用函数中修改参数值的时候,调用函数中相应实参不会发生任何变化,因为数值变化只作用在 copy 上。
为了验证上面的说法,来看一个例子
package main
import "fmt"
//简单的一个函数,实现了参数+1 的操作
func add1(a int) int {
a = a+1 // 改变了 a 的值
return a //返回一个新值
}
func main() {
x := 3
fmt.Println("x = ", x) // 应该输出 "x = 3"
x1 := add1(x) //调用 add1(x)
fmt.Println("x+1 = ", x1) // 应该输出"x+1 = 4"
fmt.Println("x = ", x) // 应该输出"x = 3"
}
虽然调用了 add1
函数,并且在 add1
中执行 a = a+1
操作,但是上面例子中 x
变量的值没有发生变化
理由很简单:因为当调用 add1
的时候, add1
接收的参数其实是 x
的 copy,而不是 x
本身。
如果真的需要传这个 x
本身,该怎么办呢?
这就牵扯到了所谓的指针。变量在内存中是存放于一定地址上的,修改变量实际是修改变量地址处的内存。只有 add1
函数知道 x
变量所在的地址,才能修改 x
变量的值。所以需要将 x
所在地址 &x
传入函数,并将函数的参数的类型由 int
改为 *int
,即改为指针类型,才能在函数中修改 x
变量的值。此时参数仍然是按 copy 传递的,只是 copy 的是一个指针。请看下面的例子
package main
import "fmt"
//简单的一个函数,实现了参数+1 的操作
func add1(a *int) int { // 请注意,
*a = *a+1 // 修改了 a 的值
return *a // 返回新值
}
func main() {
x := 3
fmt.Println("x = ", x) // 应该输出 "x = 3"
x1 := add1(&x) // 调用 add1(&x) 传 x 的地址
fmt.Println("x+1 = ", x1) // 应该输出 "x+1 = 4"
fmt.Println("x = ", x) // 应该输出 "x = 4"
}
这样,就达到了修改 x
的目的。那么到底传指针有什么好处呢?
传指针使得多个函数能操作同一个对象。
传指针比较轻量级 (8bytes),只是传内存地址,可以用指针传递体积大的结构体。如果用参数值传递的话,在每次 copy 上面就会花费相对较多的系统开销(内存和时间)。所以当要传递大的结构体的时候,用指针是一个明智的选择。
Go 语言中
channel
,slice
,map
这三种类型的实现机制类似指针,所以可以直接传递,而不用取地址后传递指针。(注:若函数需改变slice
的长度,则仍需要取地址传递指针)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论