在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
切片(slice)可以看作一种对数组的包装形式,它包装的数组为该切片的底层数组。 type slice struct { array unsafe.Pointer len int cap int }
可基于数组或数组指针创建切片,以开始和结束索引位置确定所引用的数组片段。 package main import "fmt" func main() { x := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} fmt.Println(x[:], len(x[:]), cap(x[:])) fmt.Println(x[2:5], len(x[2:5]), cap(x[2:5])) fmt.Println(x[2:5:7], len(x[2:5:7]), cap(x[2:5:7])) fmt.Println(x[4:], len(x[4:]), cap(x[4:])) fmt.Println(x[:4], len(x[:4]), cap(x[:4])) fmt.Println(x[:4:6], len(x[:4:6]), cap(x[:4:6])) } /* len cap x[:] [0 1 2 3 4 5 6 7 8 9] 10 10 x[2:5] [2 3 4] 3 8 x[2:5:7] [2 3 4] 3 5 x[4:] [4 5 6 7 8 9] 6 6 x[:4] [0 1 2 3] 4 10 x[:4:6] [0 1 2 3] 4 6 */ //[x:y:z] x:切片的起始位置 y:切片的终止位置 z:容量的终止位置 //cap表示切片所引用数组片段的真实长度 //len用于限定可读的写元素数量
和数组一样,切片同样使用索引号访问元素内容。 package main import "fmt" func main() { x := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} s := x[2:5] for i := 0; i < len(s); i++ { fmt.Println(s[i]) } } /* 2 3 4 */
可直接创建切片对象,无需预先准备数组。 package main import "fmt" func main() { s1 := make([]int, 3, 5) //make(初始化类型,长度,容量) 如果没有指定容量则与长度一致 s2 := make([]int, 3) s3 := []int{10, 20, 5: 30} //第6个元素为30 fmt.Println(s1, len(s1), cap(s1)) //[0 0 0] 3 5 fmt.Println(s2, len(s2), cap(s2)) //[0 0 0] 3 3 fmt.Println(s3, len(s3), cap(s3)) //[10 20 0 0 0 30] 6 6 }
注意下面两种定义方式。 package main import "fmt" func main() { var a []int //仅定义了一个[]int变量,并未执行初始化操作 b := []int{} //初始化表达式完成了全部创建过程 fmt.Println(a == nil, b == nil) //true false }
不支持比较操作,就算元素类型支持也不行,仅能判断是否为nil。 package main import "fmt" func main() { x := [][]int{ {1, 2}, {10, 20, 30}, {100}, } fmt.Println(x[1]) //取值 x[2] = append(x[2], 200, 300) //添加元素 fmt.Println(x) } /* [10 20 30] [[1 2] [10 20 30] [100 200 300]] */
新建切片对象依旧指向原底层数组,也就是说修改对所有关联切片可见。 package main import "fmt" func main() { d := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} s1 := d[3:7] //[3, 4, 5, 6] s2 := s1[1:3] //[4, 5] for i := range s2 { s2[i] += 100 //[104, 105] } fmt.Println(d) fmt.Println(s1) fmt.Println(s2) } /* [0 1 2 3 104 105 6 7 8 9] [3 104 105 6] [104 105] */
append向切片尾部添加数据,返回新的切片对象。 package main import "fmt" func main() { s := make([]int, 0, 5) s1 := append(s, 10) s2 := append(s1, 20, 30) fmt.Println(s, len(s), cap(s)) fmt.Println(s1, len(s1), cap(s1)) fmt.Println(s2, len(s2), cap(s2)) } /* [] 0 5 [10] 1 5 [10 20 30] 3 5 */
数组被追加到原底层数组。如果超出cap限制,则为新切片对象重新分配数组。 package main import "fmt" func main() { s := make([]int, 0, 100) s1 := s[:2:4] s2 := append(s1, 1, 2, 3, 4, 5, 6) //超出是s1 cap限制,分配新底层数组 fmt.Println("s1:", &s1[0], s1) fmt.Println("s2:", &s2[0], s2) fmt.Println("s[:10]:", s[:10]) fmt.Printf("s1 cap: %d, s2 cap: %d\n", cap(s1), cap(s2)) } /* s1: 0xc000088000 [0 0] s2: 0xc00007e040 [0 0 1 2 3 4 5 6] //数组地址不同,确认新分配 s[:10]: [0 0 0 0 0 0 0 0 0 0] //append并未向原数组中写入数据 s1 cap: 4, s2 cap: 8 //新数组是原cap的2倍,一般是2倍,但也不绝对 */
在两个切片数据间复制数据,允许指向同一底层数组,允许目标区间重叠。 package main import "fmt" func main() { s := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} s1 := s[5:8] n := copy(s[4:], s1) fmt.Println(n, s) s2 := make([]int, 6) n = copy(s2, s) fmt.Println(n, s2) } /* 3 [0 1 2 3 5 6 7 7 8 9] 6 [0 1 2 3 5 6] */
|
请发表评论