转投go系列-for循环出错问题

  • for循环错误反例:
func main() {
    
    
	in := []int{
    
    1, 2, 3, 4, 5}
	out := make([]*int, 0)
	for _, v := range in {
    
    
		//v := v  打开注释即正确
		out = append(out, &v)
	}

	fmt.Println("res:", *out[0], *out[1], *out[2])
}

期望结果:1,2,3
实际结果:5,5,5
原因:range出来的v是同一个地址,最后都指向了5
解决方案:打开注释,分配新地址再赋值

  • for循环错误反例2:
package main

import (
	"fmt"
	"sync"
)

func main() {
    
    
	var mutex sync.Mutex
	type ABC struct {
    
    
		Aa int
	}
	persons := make([]ABC, 10)
	for i, p := range persons {
    
    
		mutex.Lock()
		defer mutex.Unlock()
		p.Aa = 2
		fmt.Println("count:", i)
	}
}

大家会习惯在上锁后直接defer解锁,如果defer写到了for里面,运行就会出错啦。fatal error: all goroutines are asleep - deadlock!
两种解决方案,一种for里面不要用defer。另一种可以for里面设计个匿名函数,如下:

package main

import (
	"fmt"
	"sync"
)

func main() {
    
    
	var mutex sync.Mutex
	type ABC struct {
    
    
		Aa int
	}
	persons := make([]ABC, 10)
	for i, p := range persons {
    
    
		func() {
    
    
			mutex.Lock()
			defer mutex.Unlock()
			p.Aa = 2
			fmt.Println("count:", i)
		}()
	}
}

Guess you like

Origin blog.csdn.net/lwcbest/article/details/121361763