一些切片类型的操作
- 声明数组
- 声明切片的方式
- 给切片 append 元素
- 切片扩容的逻辑
- 遍历切片
- 协程不安全
- 解决并发安全问题|加锁
- 在指定位置插入元素
- 判断一个元素是否在切片内
- 切片去重,也可以转化成map,然后再转化回来切片就可以去重了
// 1. 声明数组
// 方式一
arr := [5]int{1, 2, 3, 4, 5}
fmt.Println(arr) // [1 2 3 4 5]
// 方式二
var arr2 [4]int
arr2[0] = 3
fmt.Println(arr2)
// 2. 声明切片的方式
// 方式一
var s1 []int
if s1 == nil {
fmt.Println("是空") // 是空
} else {
fmt.Println("不是空")
}
// 方式二
s2 := []int{}
fmt.Println(s2) // []
// 方式三
var s3 []int = make([]int, 0)
fmt.Println(s1, s2, s3) // [] [] []
// 方式四
var s4 []int = make([]int, 0, 4)
fmt.Println(s4) // []
// 方式五
s5 := []int{1, 2, 3}
fmt.Println(s5) // [1 2 3]
// 方式六
arr := [5]int{1, 2, 3, 4, 5}
var s6 []int
s6 = arr[1:4]
fmt.Println(s6) // [2 3 4]
// 3. 给切片 append 元素
arr := []int{1, 2, 3}
arr = append(arr, 4)
fmt.Println(arr) // [1 2 3 4]
// 4. 切片扩容的逻辑
// https://blog.csdn.net/weixin_43204583/article/details/127986860
// 在双倍扩容之后,还在原数组的cap范围内,就双倍扩容
// 在 1.18 版本前,切片扩容,在容量小于1024时,以2倍大小扩容。超过1024后,以1.25倍扩容。
// 在扩容后切片的基础上,会根据长度和容量进行 roundupsize 。
// 在1.18版本后,切片扩容,在容量小于256时,以2倍大小扩容。超过256后,以(1.25倍+192)扩容。
// 5. 遍历切片
arr := []string{"a", "b", "c"}
for _, v := range arr {
fmt.Println(v) // a,b,c
}
for i := 0; i < len(arr); i++ {
fmt.Println(arr[i]) // a,b,c
}
// 6. 协程不安全
arr := []int{}
var wg sync.WaitGroup
wg.Add(1000)
for i := 0; i < 1000; i++ {
go func() {
arr = append(arr, 1)
wg.Done()
}()
}
wg.Wait()
fmt.Println(len(arr)) // 957
fmt.Println(len(arr)) // 957 | 不符合期待
// 7. 解决并发安全问题|加锁
arr := []int{}
var mx sync.Mutex // sync.Mutex
var wg sync.WaitGroup
wg.Add(1000)
for i := 0; i < 1000; i++ {
go func() {
mx.Lock() // 加锁
defer mx.Unlock() // 解锁
arr = append(arr, 1)
wg.Done()
}()
}
wg.Wait()
fmt.Println(len(arr)) // 1000
// 8. 在指定位置插入元素
// https://blog.csdn.net/weixin_42161901/article/details/127935472
// 9. 判断一个元素是否在切片内
// 方案一:遍历查询,复杂度O(n)
// InSlice 判断字符串是否在 slice 中。
func InSlice(items []string, item string) bool {
for _, eachItem := range items {
if eachItem == item {
return true
}
}
return false
}
// 方案二:转成map进行查询
// ConvertStrSlice2Map 将字符串 slice 转为 map[string]struct{}。
func ConvertStrSlice2Map(sl []string) map[string]struct{} {
set := make(map[string]struct{}, len(sl))
for _, v := range sl {
set[v] = struct{}{} // struct{}{}不占用内存空间
}
return set
}
// InMap 判断字符串是否在 map 中。
func InMap(m map[string]struct{}, s string) bool {
_, ok := m[s]
return ok
}
// 10.切片去重,也可以转化成map,然后再转化回来切片就可以去重了