值与引用
Coddy Golang 中的函数和指针 课程的第 7 课,共 19 课。
到目前为止,我们已经学习了如何使用函数的参数和返回值。本课将介绍另一个在使用函数时需要了解的重要概念。
来看这样一个程序:
func main() {
a := 5
fmt.Println("value of a:", a)
sum(a)
fmt.Println("value of a after addition:", a)
}
func sum(x int) {
x = x + x
}在这个程序中,我们声明了变量 a,打印它的值,然后把它传给名为 sum 的函数。这个函数会执行加法 5 + 5。你觉得这段代码会得到什么结果?
我们运行一下看看:
value of a: 5
value of a after addition: 5值没有变化。这里有个问题,调用 sum 函数后,a 应该变成 10,对吧?
其实不是,因为在 Go 中,把值传给函数时,传递的只是它的副本。修改这个值时,函数外部不会受到影响,值只会在函数内部改变。我们可以在 sum 函数内部打印这个值来验证:
func main() {
a := 5
fmt.Println("value of a:", a)
sum(a)
fmt.Println("value of a after addition:", a)
}
func sum(x int) {
x = x + x
fmt.Println("value inside the function:", x)
}运行后,我们会得到:
value of a: 5
value inside the function: 10
value of a after addition: 5这意味着值在函数内部会改变(函数作用域内),但在函数外部,值不会改变。
我知道你需要更多细节才能理解。来看看这张图:
现在明白了吧。这样会创建一个地址不同的新变量(这对内存来说也不好!)。
这就是我们看不到变化的原因,因为这些变量并不相同😅。
要解决这个问题,我们可以使用指针,而不是传递值的副本,例如:
func main() {
a := 5
fmt.Println("value of a:", a)
sum(&a)
fmt.Println("value of a after addition:", a)
}
func sum(x *int) {
*x += *x
}现在,我们传递的不是值,而是内存地址 sum(&a)。这意味着函数会操作同一个变量,而不会创建新变量。
挑战
简单在给定的代码中,我们定义了一个用于交换两个值的函数。请补全代码,让函数正常工作并得到结果。
亲手试试
package main
import "fmt"
func swapValues(a, b int) {
a, b = b, a
}
func main() {
var x, y int = 4,10
fmt.Println("Before swap:")
fmt.Println("x =", x)
fmt.Println("y =", y)
swapValues(x, y)
fmt.Println("After swap:")
fmt.Println("x =", x)
fmt.Println("y =", y)
}
Golang 中的函数和指针中的所有课
自己练习: Go 在线编译器