在 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)
}
以下是一个基本图表,显示了需要使用指针在函数中更改其值的类型,以及不需要指针在函数中更改其值的类型。
使用指针 | 不要使用指针 |
---|---|
int | 切片 |
浮动 | 地图 |
串 | 频道 |
布尔 | 指针 |
结构 | 功能 |