概念

切片的数据结构

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线程安全

  1. 加互斥锁
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)
	}
}
  1. 使用协程来维护slice
for {
    data := <- chanList
    list = append(list, data)
}