//go_sliceproject /*
1.array和slice的区别:
a.array是有长度的,而slice是没有长度的
b.array 是值类型,而slice是引用类型
2. slice 的创建方法:
var arr = [...]int{1,2,3,4,5,6}
a. 基于array的创建
slice1 := arr[0:6]
slice1 = arr[:6]
slice1 = arr[0:]
slice1 = arr[:]
b. 基于slice 的创建
slice2 := slice1[0:3] // 基于slice创建不能超过 slice1的cap,否则会出错。
c. 直接创建
slice3 := make([]int,5,10) // cap = 10 len = 5
slice4 := []int{1,2,3,4,5,6,7,8,50:100} // 直接初始化创建赋值,len= 50+1 ,最后一个数组元素的值是100.
d. new 进行创建
sliceA := new([]int)
(*sliceA) = append((*sliceA), 1, 2, 3, 4)
3. slice 增加 、修改 、遍历、拷贝
var arr = [...]int{0,1,2,3,4,5,6}
a.slice的增加:
slice1 = arr[:]
slice1 = append(slice1 ,1,2,3)
slice2 = slice1[2:6]
slice1 = append(slice1 ,slice2...)
tips: 在slice的增加过程中,如果len>cap的话,系统会自动重新分配一个更大的slice用来储存。
b.slice的修改:
slice可以直接进行修改值,操作方法和数组一样
slice1[2] = 100
c.slice的遍历
for i := 0; i < len(slice7); i++ {
fmt.Println("first way : ", i, " = ", slice7[i])
}
for i, v := range slice7 {
fmt.Println("second way : ", i, " = ", v)
}
d.slice的拷贝
copy(slice1,slice2) // 将slice2拷贝到slice1中,
if len(slice2) > len(slice1) -> 只是从slice2中拷贝 len(slice1)个数值
相反同理。
4.slice 的原理:
slice 可以看成 底层数组 + cap(容量) + 数组偏移(数组指针)
其实质就是利用数组指针进行操作底层数组,cap是整个底层数组的len ,而 数组偏移在很多的书中表示为 slice 的 len ,可以看成是 在 cap 这个容量上,指针偏移的长度。
类似于 C++ stl 中的vector 。
在多个slice基于一个数组创建的情况下,如果一个slice对数组值进行了修改,那么所以的slice和array相应
位置的值都会变化,原因是因为,他们操作的属于同一个底层数组,下面代码说明一下
var arr = [...]int{1,2,3,4}
slice1 := arr[1:4] // 2,3,4
slice2 := slice1[1:3] // 3,4
slice2[0] = 100
输出结果:arr: [1 2 100 4]
slice1: [2 100 4]
slice2: [100 4]
在这里 arr 就相当于 slice1 和slice2 的底层数组 ,而slice 只是在底层数组上做的指针的偏移。
*/package main import ( "fmt" ) func main() { var arr = [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} var slice1 []int = arr[0:6] //0 1 2 3 4 5 6 slice2 := slice1[2:7] slice3 := make([]int, 5, 10) slice3[4] = 10 slice3 = append(slice3, 11) slice4 := []int{0, 1, 2, 3, 4, 15: 1} fmt.Println("slice1's cap = ", cap(slice1), "slice1's len = ", len(slice1), "\r\n", slice1) fmt.Println("slice2's cap = ", cap(slice2), "slice2's len = ", len(slice2), "\r\n", slice2) fmt.Println("slice3's cap = ", cap(slice3), "slice3's len = ", len(slice3), "\r\n", slice3) fmt.Println("slice4's cap = ", cap(slice4), "slice4's len = ", len(slice4), "\r\n", slice4) slice5 := arr[:] slice5 = append(slice5, 11, 22, 33, 44, 55, 66) fmt.Println(slice5) slice6 := slice5[4:8] slice5 = append(slice5, slice6...) fmt.Println(slice5) slice7 := arr[:] slice7[2] = 100 fmt.Println("slice1[2]=", slice1[2]) fmt.Println("slice7[2]=", slice7[2]) fmt.Println("array[2]=", arr[2]) for i := 0; i < len(slice7); i++ { fmt.Println("first way : ", i, " = ", slice7[i]) } for i, v := range slice7 { fmt.Println("second way : ", i, " = ", v) } copy(slice5, slice6) fmt.Println(slice5) copy(slice6, slice5) fmt.Println(slice6) var array = [...]int{1, 2, 3, 4} slice8 := array[1:4] // 2,3,4 slice9 := slice8[1:3] // 3,4 fmt.Println(array, slice8, slice9) slice9[0] = 100 fmt.Println(array, slice8, slice9) }