定义切片

切片(Slice):Go 语言切片是对数组的抽象。

Go 数组的长度不可改变,但是提供了一种灵活,功能强悍的内置类型切片(“动态数组”),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
var s []int
fmt.Printf("value=%v len=%d cap=%d\n", s, len(s), cap(s))

s1 := []int{2, 4, 6, 8}
fmt.Printf("value=%v len=%d cap=%d\n", s1, len(s1), cap(s1))

s2 := make([]int, 16)
fmt.Printf("value=%v len=%d cap=%d\n", s2, len(s2), cap(s2))

s3 := make([]int, 10, 32)
fmt.Printf("value=%v len=%d cap=%d\n", s3, len(s3), cap(s3))

// 结果
value=[] len=0 cap=0
value=[2 4 6 8] len=4 cap=4
value=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] len=16 cap=16
value=[0 0 0 0 0 0 0 0 0 0] len=10 cap=32

对数组进行切片

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
func main() {
    arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
    fmt.Println("arr[2:6] =", arr[2:6])
    fmt.Println("arr[:6] =", arr[:6])
    fmt.Println("arr[2:] =", arr[2:])
    fmt.Println("arr[:] =", arr[:])
}

// 结果
arr[2:6] = [2 3 4 5]
arr[:6] = [0 1 2 3 4 5]
arr[2:] = [2 3 4 5 6 7]
arr[:] = [0 1 2 3 4 5 6 7]

Slice 本身没有数据,是对底层 array 的一个 view

1
2
3
4
5
6
arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
s := arr[2:6]
s[0] = 10
fmt.Println(arr)
// 结果
[0 1 10 3 4 5 6 7]
1
2
3
4
5
6
7
s := arr[2:6]
s = s[:3]
s = s[1:]
s = arr[:]
fmt.Println(s)
// 结果
[0 1 2 3 4 5 6 7]

Slice 扩展

1
2
3
4
5
6
7
8
func main() {
    arr := [...]int{0, 1, 2, 3, 4, 5, 6}
    s1 := arr[2:6]
    s2 := s1[3:5]
    fmt.Printf("s1=%v s2=%v\n", s1, s2)
}
// 结束
s1=[2 3 4 5] s2=[5 6]
  • slice 可以向后扩展,不可以向前扩展
  • s[i] 不可以超越len(s),向后扩展不可以超越底层数组cap(s)

slice 添加元素

1
2
3
4
5
6
7
8
9
arr := [...]int{0, 1, 2, 3, 4, 5, 6}
s1 := arr[2:6]
s2 := s1[3:5]
s3 := append(s2, 10)
s4 := append(s3, 11)
s5 := append(s4, 12)
fmt.Printf("s3=%v s4=%v s5=%v arr=%v",s3, s4, s5, arr)
// 结果
s3=[5 6 10] s4=[5 6 10 11] s5=[5 6 10 11 12] arr=[0 1 2 3 4 5 6]
  • 添加元素时如果超越 cap,系统会重新分配更大的底层数组
  • 由于值传递的关系,必须接收 append 的返回值,s=append(s,val)

copy

1
2
3
4
5
6
s1 := []int{2, 4, 6, 8}
s2 := make([]int, 16)
copy(s2, s1)
fmt.Printf("value=%v len=%d cap=%d\n", s2, len(s2), cap(s2))
// 结果
value=[2 4 6 8 0 0 0 0 0 0 0 0 0 0 0 0] len=16 cap=16

删除值为8,代码

1
2
3
4
s2 = append(s2[:3],s2[4:]...)
fmt.Printf("value=%v len=%d cap=%d\n", s2, len(s2), cap(s2))
// 结果
value=[2 4 6 0 0 0 0 0 0 0 0 0 0 0 0] len=15 cap=16

s2[4:]... 展开这个切片

delete

删除 s2 头、尾元素

1
2
3
4
5
s2 = s2[1:]
s2 = s2[:len(s2)-1]
fmt.Printf("value=%v len=%d cap=%d\n", s2, len(s2), cap(s2))
// 结果
value=[4 6 0 0 0 0 0 0 0 0 0 0 0] len=13 cap=15

The End!