我想问在引用类型(切片、映射、通道、指针和函数)中声明指针是否有一些好处。
例如:
package main
import (
"fmt"
)
func main() {
s := []string{"one", "two"}
changeValue(0, s)
fmt.Println(s)
s = []string{"one", "two"}
changeValue2(0, &s)
fmt.Println(s)
}
func changeValue(i int, v []string) {
v[i] = "newOne"
}
func changeValue2(i int, v *[]string) {
(*v)[i] = "newOne"
}
两种方法都有效,但我的问题是第二种方法是否有任何优势。
第一种方法应该创建切片的副本,但它最终是有效的,因为切片类型的性质,它在内部保存指针。
第二种方法不创建任何副本,最终执行相同的操作。 编辑:我认为这种说法是不正确的,第二种方法也创建了一个副本,但只是用了一个指针。
也许出于可读性的原因对此达成了一些共识,或者潜在的改进可能还不够显着而引人注目。
使用指向切片(或其他引用类型)的指针确实存在差异。
避免切片复制:虽然两种方法达到相同的结果,但使用指针(*[]string)的第二种方法不会创建切片本身的副本。相反,它指向原始切片。相反,第一种方法 ([]string) 在作为参数传递时创建切片的新副本。这里的切片指的是切片头,它是包含容量、长度和底层数据引用的元数据。
可变性和意图:使用指针允许您直接修改原始切片,这意味着函数调用可以更改切片头。 这也传达了该函数可能会修改原始切片的意图,并明确表示不会创建副本。这是与该功能的下游用户沟通的一种方式。