数组
1 | // 索引数组 |
切片
切片与数组的定义区别
1 | vs:=[]interface{}{ |
Reslice
- 切片本质上是指向类型
- 切片不能越界,如果超过底层数组,则报错,而不是追加数组长度
- 索引不可超多数组容量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15a := [10]int{1,2,3,4,5,6,7,8,9}
fpm.Prinln(a)
// 0~4 容量为10
s1 := a[:5]
// 5-9, 索引5到索引9,索引10不取, 容量为5
s1 := a[5,10]
// 使用make,
// 参数1:类型,
// 参数2:包含几个元素,
// 参数3:容量(先分配10个连续内存地址,如果增加到11个时,则需要从新分配,每次增加一倍,扩容至20,下次40,在下次80,造成这种现象的原因是因为:从新分配内存是一件效率非常低的)如果留空,则和参数相等
s1 := make([]int,3,10)
// 获取切片的长度,
len(s1)
// 获取切片容量
map(s1)
Append
- 可以在slice尾部追加元素
- 可以将一个slice追加到另一个slice
- 如果最终长度未超过追加到slice的容量,则返回原始slice
- 如果超过追加的slice的容量,将重新分配数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 s1 := make([]int, 3, 6)
fmt.Printf("%p\n", s1)
s1 = append(s1, 1, 2, 3)
fmt.Printf("%v %p\n", s1, s1)
s1 = append(s1, 1, 2, 3)
fmt.Printf("%v %p\n", s1, s1)
// 对于指向同一个数组的slice,如果数组改变了,则两个slice指向的部分同样改变
a := []int{1, 2, 3, 4, 5}
s1 := a[2:5]
s2 := a[1:3]
fmt.Println(s1, s2)
s1[0] = 9
fmt.Println(s1, s2)
// 结果:
➜ first go run helloworld.go
[3 4 5] [2 3]
[9 4 5] [2 9]
- 如果一个slice通过append添加时,如果超过了容量,那么就不在指向原来的数组,而是从新分配了一个
1
2
3
4
5
6
7
8
9
10
11
12
13 func main() {
a := []int{1, 2, 3, 4, 5}
s1 := a[2:5]
s2 := a[1:3]
fmt.Println(s1, s2)
s2 = append(s2, 1, 2, 3, 4, 5, 5, 6, 6, 7)
s1[0] = 9
fmt.Println(s1, s2)
}
// 结果:
➜ first go run helloworld.go
[3 4 5] [2 3]
[9 4 5] [2 3 1 2 3 4 5 5 6 6 7]
copy
- 从参数2复制到参数1(覆盖)
- 该函数主要是切片(slice)的拷贝,不支持数组
- 将第二个slice里的元素拷贝到第一个slice里,拷贝的长度为两个slice中长度较小的长度值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16s1 := []int{1, 2, 3, 4, 5, 6}
s2 := []int{7, 8, 9}
copy(s2, s1)
copy(s1, s2)
fmt.Println(s2, s1)
// 结果
➜ first go run helloworld.go
[1 2 3] [1 2 3 4 5 6]
// 当然可以指定位置
s1 := []int{1, 2, 3, 4, 5, 6}
s2 := []int{7, 8, 9}
copy(s1[3:6], s2)
fmt.Println(s1)
// 结果:
➜ first go run helloworld.go
[1 2 3 7 8 9]
删除切片
1 | // 比如想删除下标为k的切片 |
map
- map是无序的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 // 初始化map
m := map[int]string{1: "zhangsan", 2: "lisi", 3: "wangwu", 4: "zhaoliu"}
// 初始化slice
s := make([]int, len(m))
i := 0
// range 可遍历slice或map
for k, _ := range m {
// 将map的键赋给slice
s[i] = k
i++
}
fmt.Println(s)
//结果(体现了map的无序性)
➜ first go run helloworld.go
[1 2 3 4]
➜ first go run helloworld.go
[4 1 2 3]
// 如果使用range遍历slice和map,
func main() {
m := map[int]string{1: "zhangsan", 2: "lisi", 3: "wangwu", 4: "zhaoliu"}
s := make([]int, len(m))
i := 0
for k, v := range m {
s[i] = k
i++
fmt.Println(k, v)
}
fmt.Println(s)
for k, v := range s {
fmt.Println(k, v)
}
}
// 结果如下:
➜ first go run helloworld.go
4 zhaoliu
1 zhangsan
2 lisi
3 wangwu
[4 1 2 3]
0 4
1 1
2 2
3 3