揭秘 Go 中的函数参数

在 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 没有真正的“引用类型”
完全取决于理解不同类型的内部构建方式。

  • 映射和通道基本上是内部指针,
  • 而切片是带有指向数组指针的结构。