Day08(切片 slice 和 range)
切片(slice
) 和 range
使用
切片(slice
)
Go 数组在一定情况下,不能满足开发业务需求(数组固定长度、有很多局限性),切片是可变长度序列,切片底层就是数组做了一层封装(也叫做动态数组)。切片可以自动扩容,切片是引用类型,包含地址、长度(
len
)、容量(cap
)
切片什么时候扩容
- 如果切片的容量小于 1024 个元素,那么扩容的时候
slice
的cap
就翻番,乘以 2;一旦元素个数超过 1024 个元素,增长因子就变成 1.25,即每次增加原来容量的四分之一。 - 如果扩容之后,还没有触及原数组的容量,那么,切片中的指针指向的位置,就还是原数组,如果扩容之后,超过了原数组的容量,那么,Go 就会开辟一块新的内存,把原来的值拷贝过来,这种情况丝毫不会影响到原数组
- 首先判断,如果新申请容量(
cap
)大于 2 倍的旧容量(old.cap
),最终容量(newcap
)就是新申请的容量(cap
)。 - 否则判断,如果旧切片的长度小于 1024,则最终容量(
newcap
)就是旧容量(old.cap
)的两倍,即(newcap=doublecap
), - 否则判断,如果旧切片长度大于等于 1024,则最终容量(
newcap
)从旧容量(old.cap
)开始循环增加原来的 1/4,即(newcap=old.cap,for {newcap += newcap/4}
)直到最终容量(newcap
)大于等于新申请的容量(cap
),即(newcap >= cap
) - 如果最终容量(
cap
)计算值溢出,则最终容量(cap
)就是新申请容量(cap
)。
基本使用
- 定义方式
指定长度与容量:
make([]Type, length, capacity)
指定长度:
make([]Type, length)
1
2
3
4
5
6
7
8
9
10
package main
import "github.com/Cc360428/HelpPackage/UtilsHelp/logs"
func main() {
var slice1 []string
logs.Info(slice1)
slice2 := make([]int, 1, 2)
logs.Info(len(slice2), cap(slice2))
}
1
2
2020/04/24 23:47:25.578 [I] [slice.go:7] []
2020/04/24 23:47:25.621 [I] [slice.go:9] 1 2
- 初始化以及切割
1
2
3
a[2:] // 等同于 a[2:len(a)]
a[:3] // 等同于 a[0:3]
a[:] // 等同于 a[0:len(a)]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package main
import "github.com/Cc360428/HelpPackage/UtilsHelp/logs"
func main() {
s := []int{1, 2, 3}
logs.Info(s)
s1 := s[:1]
logs.Info(s1)
s2 := s[1:]
logs.Info(s2)
s3 := s[1:2]
logs.Info(s3)
}
1
2
3
4
2020/04/24 23:55:30.339 [I] [slice2.go:7] [1 2 3]
2020/04/24 23:55:30.366 [I] [slice2.go:9] [1]
2020/04/24 23:55:30.366 [I] [slice2.go:11] [2 3]
2020/04/24 23:55:30.366 [I] [slice2.go:13] [2]
len()
和cap()
1
2
3
4
5
6
7
8
9
10
11
12
package main
import "github.com/Cc360428/HelpPackage/UtilsHelp/logs"
func main() {
// 定义长度为:1 ,容量为2
s1 := make([]int, 1, 2)
logs.Info(len(s1), cap(s1))
s2 := make([]int,6)
s1 = append(s1, s2...)
logs.Info(len(s1), cap(s1))
}
1
2
2020/04/25 00:01:32.871 [I] [slice3.go:8] 1 2
2020/04/25 00:01:32.899 [I] [slice3.go:11] 7 8
append()
和copy()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main
import "github.com/Cc360428/HelpPackage/UtilsHelp/logs"
func main() {
var s []int
logs.Info(s, len(s), cap(s))
s = append(s, 0)
logs.Info(s, len(s), cap(s))
s = append(s, 612, 12, 3132, 1024)
logs.Info(s, len(s), cap(s))
s2 := make([]int, len(s))
s2[0] = 888
s2[1] = 999
s2[2] = 666
s = append(s, s2 ...)
logs.Info(s, len(s), cap(s))
s3 := make([]int,5)
copy(s3, s2)
logs.Info(s3, len(s3), cap(s3))
}
1
2
3
4
5
2020/04/25 00:14:53.179 [I] [slice4.go:7] [] 0 0
2020/04/25 00:14:53.213 [I] [slice4.go:9] [0] 1 1
2020/04/25 00:14:53.213 [I] [slice4.go:11] [0 612 12 3132 1024] 5 6
2020/04/25 00:14:53.213 [I] [slice4.go:17] [0 612 12 3132 1024 888 999 666 0 0] 10 12
2020/04/25 00:14:53.213 [I] [slice4.go:20] [888 999 666 0 0] 5 5
删除元素和 sort.Ints()
排序
总结一下就是:要从切片 a 中删除索引为
index
的元素,操作方法是a = append(a[:index], a[index+1:]...)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package main
import (
"github.com/Cc360428/HelpPackage/UtilsHelp/logs"
"sort"
)
// 删除索引为2
func main() {
a := []int{1, 2, 3,9, 5, 6, 7, 8}
a = append(a[:2], a[3:]...)
logs.Info(a)
sort.Ints(a)
logs.Info(a)
}
1
2
2020/04/25 00:21:05.501 [I] [slice5.go:12] [1 2 9 5 6 7 8]
2020/04/25 00:21:05.535 [I] [slice5.go:14] [1 2 5 6 7 8 9]
range
for
遍历循环迭代array
、slice
、channel
、map
1
2
3
for k ,v := range Type{
fmt.Println(k,v)
}
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
package main
import (
"github.com/Cc360428/HelpPackage/UtilsHelp/logs"
)
func main() {
// array
array := []int{1, 2, 3, 4}
for k, v := range array {
logs.Info(k, v)
}
slice := make([]int, 3)
for k, v := range slice {
logs.Info(k, v)
}
// slice
channel := make(chan int, 2)
go func() {
for i := 1; i <= 3; i++ {
channel <- 8 * i
}
defer close(channel)
// !close(channel) --> fatal error: all goroutines are asleep - deadlock!
}()
// channel
for k := range channel {
logs.Info("channel", k)
}
// map
mapType := make(map[string]interface{})
mapType["name"] = "lcc"
mapType["age"] = 18
for k, v := range mapType {
logs.Info(k, v)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2020/04/25 09:47:23.485 [I] [range.go:11] 0 1
2020/04/25 09:47:23.510 [I] [range.go:11] 1 2
2020/04/25 09:47:23.510 [I] [range.go:11] 2 3
2020/04/25 09:47:23.510 [I] [range.go:11] 3 4
2020/04/25 09:47:23.510 [I] [range.go:15] 0 0
2020/04/25 09:47:23.510 [I] [range.go:15] 1 0
2020/04/25 09:47:23.510 [I] [range.go:15] 2 0
2020/04/25 09:47:23.510 [I] [range.go:28] channel 8
2020/04/25 09:47:23.510 [I] [range.go:28] channel 16
2020/04/25 09:47:23.511 [I] [range.go:28] channel 24
2020/04/25 09:47:23.511 [I] [range.go:35] name lcc
2020/04/25 09:47:23.511 [I] [range.go:35] age 18
This post is licensed under
CC BY 4.0
by the author.