如何判断slice是否为空
判断slice是否为空,不能与nil进行比较做判断,因为slice有可能已初始化。而是应该使用len计算长度。
例如
package main
import (
"fmt"
)
func main() {
var slice1 []int
slice2 := []int{}
fmt.Println("slice1 == nil:", slice1 == nil)
fmt.Println("slice1 len:", len(slice1))
fmt.Println("slice2 == nil:", slice2 == nil)
fmt.Println("slice2 len:", len(slice2))
}
output:
slice1 == nil: true
slice1 len: 0
slice2 == nil: false
slice2 len: 0
slice的并发读写
slice不是并发安全的。
看下面的例子,在并发append数据过程中,数据会有丢失。
package main
import (
"fmt"
"time"
)
var slice1 []int
func appendValue(i int) {
slice1 = append(slice1, i)
}
func main(){
for i := 0; i<10000; i++ {
go appendValue(i)
}
time.Sleep(time.Second)
for i, v := range slice1 {
fmt.Println(i,v)
}
}
output:
...
7516 9996
7517 9995
7518 9997
7519 9998
7520 9999
从输出可以看到,slice不是并发安全的,数据有丢失。
如何达到并发安全?
加锁是一种方式。
看下面的例子,通过加锁,达到互斥效果,实现并发安全。
package main
import (
"fmt"
"sync"
"time"
)
var slice1 []int
var lock sync.Mutex
func appendValue(i int) {
lock.Lock()
defer lock.Unlock()
slice1 = append(slice1, i)
}
func main(){
for i := 0; i<10000; i++ {
go appendValue(i)
}
time.Sleep(time.Second)
for i, v := range slice1 {
fmt.Println(i,v)
}
}
output:
9991 9627
9992 9991
9993 9995
9994 9993
9995 9992
9996 9998
9997 9278
9998 9948
9999 9999
从输出可以看到,数据没有丢失,可以正常打印。