/* 切片没有自己的任何数据,它只是底层数组的一个表示。对切片所做的任何修改都将反映在底层数组中。 */ a := [5]int{1, 2, 3, 4, 5} b := a[:3] c := make([]int, 2, 5) //make一般是2个参数,第三个参数为预留参数,定义slice的cap大小 for i := 0; i < len(b); i++ { b[i]++ } fmt.Println(a) //此处,a的部分元素的值发生了改变 fmt.Println(reflect.TypeOf(b)) fmt.Println(c) c[0] = 1 //c = append([]int{2}, []int{2, 3}...) c = c[:cap(c)] //需要重新分配切片才能试用cap-len的预留空间 fmt.Println(c, len(c), cap(c)) s := []int{1, 2, 3} v := s fmt.Println("a", s[2:]) //s[1] = 3 s = append(s[:1], s[2], s[2], s[2]) //s[:1] = 数组s中的元素1,append s[2:]时,其容量是够的,会在s[0]后面接一个元素s[2],导致底层数组[1,2,3]变成[1,3,3] fmt.Println("s的容量为", cap(s)) s = s[:cap(s)] s[5] = 1 fmt.Println(s) fmt.Println("v=", v) //此时v仍指向旧数组[1,2,3] fmt.Println("s=", s) //由于原切片s[:1]执行append,容量不足以装下3个数,会重新分配新的底层数组 d := make([]int, 4, 4) d[0] = 1 d[1] = 2 fmt.Println(cap(d)) d = append(d[:2], []int{22, 34, 66}...) fmt.Println(d, len(d), cap(d)) m := make([]int, 2, 4) m = append(m, 1) m = append(m, 2) //执行到这一步之后,slice的容量满了,下一步继续append会使底层丢弃原有的数组,重建一个数组,此时cap = 2 * max(len(m),len(params)) = 8 fmt.Println(cap(m)) m = append(m, 3) fmt.Println("m=", m, len(m), cap(m)) aa := []byte{1, 3, 4} aa = append(aa, 1) fmt.Println("aa的容量为", cap(aa)) //byte扩容后的cap是 3 * 2 -> 8 没有6字节一说,所以向上取最小为8字节 cc := []int32{1, 23} cc = append(cc, 2, 5, 6) fmt.Println("cap of cc is ", cap(cc)) var aaa byte = 1 var bbb int32 = 1 fmt.Println(unsafe.Sizeof(aaa)) fmt.Println(unsafe.Sizeof(bbb))
golang内部对于内置类型, 有着特定的扩容方式,而对于自定义类型的切片的容量计算就是直接 cap = oldcap + append()函数中追加的容量