zoukankan      html  css  js  c++  java
  • golang两种在for循环中使用goroutine的错误形式

    1. 闭包中使用循环体中变化的量

    platground链接:

    https://play.golang.org/p/6x6_tuQNjUO

    type Value struct{
    	val int
    }
    
    func (v *Value)print(){
    	time.Sleep(time.Second)
    	fmt.Println(v.val)
    }
    
    func main() {
    
    	vals := make([]Value,0)
    
    	for  i := 0; i <10;i++ {
    		vals = append(vals, Value{val:i,})
    	}
    
    	for _,v := range vals{
    		// 这种形式,闭包方式共享了主协程的变量v
    		// 而变量v是不断变化的,所以导致print的值都是最后一个
    		go func(){
    		   v.print()	
    		}()
    	}
    
    	time.Sleep(time.Second*3)
    }
    
    
    运行结果:
    9
    9
    9
    9
    9
    9
    9
    9
    9
    9
    

    2. receiver为指针时候,创建goroutine

    playground链接:
    https://play.golang.org/p/6quZIn6ZwSM

    type Value struct{
    	val int
    }
    
    func (v *Value)print(){
    	time.Sleep(time.Second)
    	fmt.Println(v.val)
    }
    
    func main() {
    
    	vals := make([]Value,0)
    
    	for  i := 0; i <5;i++ {
    		vals = append(vals, Value{val:i,})
    	}
    
    	for _,v := range vals{
    		// print方法的receiver是(*Value)类型,而此处v是一个Value类型
    		// 所以每次print传值都传递了&v。
    		// 在for loop中,v的值变化,但是&v不会改变
    		// 在其他goroutine中执行时,print的内容不可预期,取决于当时的v值
    		go v.print()
    	}
    
    	time.Sleep(time.Second*3)
    }
    
    运行结果:
    4
    4
    4
    4
    4
    
  • 相关阅读:
    网络配置
    数据管理
    仓库
    dockerfile
    docker 概念
    查看日志小技巧
    springboot缓存
    360笔试算法题 AT变换
    删除链表里全部重复元素以及删除链表重复元素只保留一个
    报错类型
  • 原文地址:https://www.cnblogs.com/gexin/p/10936565.html
Copyright © 2011-2022 走看看