深淺拷貝
在很多編程語言都有深淺拷貝的這個概念,當然golang也不例外i,在go語言中值類型賦值都是深拷貝,引用類型一般都是淺拷貝,其本質就是,深拷貝會拷貝數據,而淺拷貝只會拷貝內存的地址,所有就會出現,像slice那樣修改底層數組的值,slice的值也跟着改動。
深拷貝
修改a的值b不變,說明是值的拷貝,
func main() { var a = 123 b := a fmt.Println(a, b) a = 456 fmt.Println(a, b) }
淺拷貝
修改a的值,b的值也跟着修改了,原因是兩個slice指向同一個內存地址,所以得出記錄slice拷貝是淺拷貝
func main() { a := []int{1, 2, 3} b := a fmt.Println(a, b) a[0] = 1000 fmt.Println(a, b) }
slice深拷貝
可以通過內置的copy函數實現,也可以使用append生成一個新的
func main() { a := []int{1, 2, 3} b := make([]int, 0) b = append(b, a[:]...) fmt.Println(a, b) a[1] = 1000 fmt.Println(a, b) fmt.Printf("%p,%p", a, b) }
copy函數
需要注意的是copy函數不會擴容,也就是要復制的slice比原slice要大的時候,只會把容量占滿多余的移除。
func main() { slice1 := []int{1, 2, 3, 4, 5} slice2 := []int{5, 4, 3} copy(slice2, slice1) // 只會復制slice1的前3個元素到slice2中 fmt.Println(slice1, slice2) copy(slice1, slice2) // 只會復制slice2的3個元素到slice1的前3個位置 fmt.Println(slice1, slice2) }