goroutine和闭包
for i:= 0; i < 10; i++ {
go func(){
time.Sleep(time.Duration(100) * time.Millisecond)
fmt.Printf("%d\n", i)
}()
}
预期:输出0~9
实际:输出全部是10
原因:在10个goroutine中,输出的 i
都是for
循环这个scope
里的 i
,这个值在 for
循环中已经发生了变化,最后维持在10
可以修改成:
for i:= 0; i < 10; i++ {
go func(int _i){
time.Sleep(time.Duration(100) * time.Millisecond)
fmt.Printf("%d\n", _i)
}(i)
}
传值和WaitGroup
func run(taskcount int) {
group := sync.WaitGroup{}
group.Add(taskcount)
for i:=0; i < taskcount; i++ {
go doTask(group)
}
group.Wait()
}
func doTask(group sync.WaitGroup) {
dosometing()
group.Done()
}
预期:run能够正确执行
实际:group.Wait()
一直无法结束
原因:调用的doTask
的时候group
是值拷贝方式,在doTask
中修改group
不会影响run
中的group
,所以group.Wait()
一直阻塞
可以修改成:
func run(taskcount int) {
group := sync.WaitGroup{}
group.Add(taskcount)
for i:=0; i < taskcount; i++ {
go doTask(&group)
}
group.Wait()
}
func doTask(group *sync.WaitGroup) {
dosometing()
group.Done()
}
strings.Compare and make
func byteToString() byte[] {
s := "ABCDEFG"
byteArray := make([]byte, len(s))
for _, c := range s {
byteArray = append(byteArray, c)
}
byteS := string(byteArray)
// byteS contains exrta bytes as make inits it with size len(s)
fmt.Printf("equal by ==? %v\n", byteS == s)
fmt.Printf("equal by strings.Compare? %v\n", strings.Compare(byteS, s) == 0)
}
output:
equal by ==? false
equal by strings.Compare? true