切片的数据结构
type slice struct {
array unsafe.Pointer
len int
cap int
}
包含一个指针,指向底层的数组,还有长度和容量。
切片的长度和容量
The length of a slice is the number of elements it contains.
The capacity of a slice is the number of elements in the underlying array, counting from the first element in the slice.
扩容规则
1、 如果原slice的容量小于1024,则新slie的容量将扩大为原来的2倍
2 、如果原slice的容量大于或等于1024,则新slice的容量将扩大为原来的1.25倍
创建,修改,查询
定义、初始化切片
// 定义
var a []int
// 初始化
a := []int{1,2,3}
a := make([]int, len)
插入其他切片的元素
a :=[] int {1,2,3 }
b :=[] int {4,5,6 }
a = append(a, b...)
fmt.Println(a) // [1 2 3 4 5 6]
遍历
var arr [5]int
// way1
for i, v:= range arr {
fmt.Println(i)
fmt.Println(v)
}
// way2
for i:= range arr{
fmt.Println(i)
fmt.Println(arr[i])
}
二维切片
创建
func main() {
// 创建
res := make([][]int, row)
for i := range res {
res[i] = make([]int, column)
}
fmt.Println(res)
// 遍历
for i, row := range res {
for j, value := range res[i] {
fmt.Print(res[i]][j])
}
}
}
线程安全性
slice是非线程安全的,因为底层数组是通过指针来引用的,该指针是非线程安全的(索引位覆写)。
如何让slice线程安全
- 加互斥锁
var s []int
var lock sync.Mutex
func appendSlice(i int) {
lock.Lock()
s = append(s, i)
lock.Unlock()
}
func main() {
for i := 0; i < 10000; i++ {
go appendSlice(i)
}
time.Sleep(time.Second)
for i, v := range s {
fmt.Println(i, ":", v)
}
}
- 使用协程来维护slice
for {
data := <- chanList
list = append(list, data)
}