在 Go 中,函数始终使用传入参数的副本
func incrementScore(s int) { s += 10 }
func main() { score := 20 incrementScore(score) fmt.Println(score) // Still prints 20! }
|
如果您确实想更改这些值,主要有两种方法可以实现:
1、对基本类型、结构和数组使用指针参数:
func incrementScore(s *int) { *s += 10 }
func main() { score := 20 incrementScore(&score) fmt.Println(score) // Now prints 30! }
|
2、使用map、切片和通道,它们的行为因其内部工作方式不同而不同:
func addBonus(scores map[string]int) { for name := range scores { scores[name] += 10 } }
func main() { scores := map[string]int{"Alice": 20} addBonus(scores) fmt.Println(scores) // Prints map[Alice:30] }
|
但是使用时要注意切片的一个小怪癖append()。如果你想让更改显示在调用函数中,你必须使用指向切片的指针:
func addScores(s *[]int, values ...int) { *s = append(*s, values...) }
func main() { scores := []int{10, 20} addScores(&scores, 30, 40) fmt.Println(scores) // Prints [10 20 30 40] }
|
最大的注意:
Go 没有真正的“引用类型”
完全取决于理解不同类型的内部构建方式。
- 映射和通道基本上是内部指针,
- 而切片是带有指向数组指针的结构。