package main
import (
"fmt"
)
func main() {
s := []int{1, 2, 3}
ss := s[1:]
for i := range ss {
ss[i] += 10
}
fmt.Println(s)
ss = append(ss, 4)
for i := range ss {
ss[i] += 10
}
fmt.Println(s)
}
结果是
[1 12 13]
[1 12 13]
也就是说第一个循环改变了 s,第二个循环没有改变。
为什么会这样呢,因为在第一个循环中,s 和 ss 都是 slice,底层共用的是一个数组,所以改变 ss 的时候,实际上改变的是底层的数组,所以 s 也会跟着改变。
在第二个循环中,ss = append(ss, 4)
这句话会将 ss 底层引用的数组改变,所以从这里开始 s 和 ss 就没有关联了。所以改变 ss 的时候,并不会改变 s。
可以打印出 slice 的底层数组印证一下:
package main
import (
"fmt"
"reflect"
"unsafe"
)
func printArrayOfSlice(msg string, s []int) {
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&s))
data := *(*[3]int)(unsafe.Pointer(hdr.Data))
fmt.Printf("%s \tarray\t%+v\n", msg, data)
}
func main() {
s := []int{1, 2, 3}
ss := s[1:]
for i := range ss {
ss[i] += 10
}
printArrayOfSlice("s", s)
printArrayOfSlice("ss", ss)
ss = append(ss, 4)
for i := range ss {
ss[i] += 10
}
printArrayOfSlice("s", s)
printArrayOfSlice("ss", ss)
}
结果是
s array [1 12 13]
ss array [12 13 842350739296]
s array [1 12 13]
ss array [22 23 14]
说明的我的想法:ss 在前后所引用底层数组改变了。