在 Go 中,一切都是按值传递的。使用值调用函数会导致值被复制,并且函数只能访问值的副本。
指针语义允许“按值”传递的东西以一种更新“原始”值的方式,就像我们将指针传递给它一样。
什么类型有指针语义?
Go 中的哪些类型需要使用指针来修改函数内的值,哪些类型不需要?
所有类型的变量都需要使用指针,如果你想修改传递给函数的值。
唯一的例外是,某些引用类型可能会在不传递指针的情况下修改其成员,但不使用指针则无法修改类型值。
修改切片成员(但不是切片本身)的示例(playground):
func main() {
s := []int{1, 2, 3, 4}
modifySliceMember(s)
fmt.Println(s) // [90 2 3 4]
}
func modifySliceMember(s []int) {
if len(s) > 0 {
s[0] = 99
}
}
修改切片本身(playground):
func main() {
s := []int{1, 2, 3, 4}
modifySlice(&s)
fmt.Println(s) // []
}
func modifySlice(s *[]int) {
*s = make([]int, 0)
}
但是请注意,即使在这种情况下,严格来说我们并没有真正改变传递的值。在这种情况下传递的值是一个指针,并且该指针无法更改。