Go 函数的参数传递
在 Go 中,函数通过值传递或引用传递传递参数。了解这两种传递方式之间的差异对于优化代码性能和避免意外行为至关重要。
值传递
当以值传递方式传递参数时,函数会收到参数值的副本。这意味着对参数值的任何修改都不会影响函数外的原始参数。值传递对于不可变类型(例如 int、float64 和 string)很有用,因为即使在函数中更改了它们的值,原始值也会保持不变。
代码示例:
package main
import "fmt"
func addValue(n int) {
n++
}
func main() {
num := 10
addValue(num)
fmt.Println(num) // 输出:10
}
引用传递
当以引用传递方式传递参数时,函数会收到参数的地址。这意味着对参数值的任何修改都将反映在函数外部的原始参数上。引用传递对于可变类型(例如数组、切片和映射)很有用,因为我们需要在函数中修改原始值。
要在 Go 中实现引用传递,可以使用指针(*)。指针是变量地址的引用。
代码示例:
package main
import "fmt"
func addValuePtr(n *int) {
*n++
}
func main() {
num := 10
addValuePtr(&num)
fmt.Println(num) // 输出:11
}
实战案例
考虑以下函数,它计算数字数组中所有数字的总和:
func sum(nums []int) int {
total := 0
for _, num := range nums {
total += num
}
return total
}
如果我们尝试使用值传递向此函数传递数组,则在函数内部对数组元素的任何修改都不会影响函数外的原始数组。相反,我们需要使用引用传递,以便函数可以访问原始数组并修改其元素:
func main() {
nums := []int{1, 2, 3, 4, 5}
sumPtr(&nums)
fmt.Println(nums) // 输出:[6 7 8 9 10]
}
func sumPtr(nums *[]int) {
for i, num := range *nums {
(*nums)[i] = num + 1
}
}