golang range for循环中如何正确的给goroutine传参

Posted waken-captain

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang range for循环中如何正确的给goroutine传参相关的知识,希望对你有一定的参考价值。

1.code example

 公共方法

func testDomain(ii string) {
	time.Sleep(time.Second * 4)
	fmt.Printf("pid: %d___point addr: %d___%s 
", GoID(), &ii, ii)
}
func GoID() int {
	var buf [64]byte
	n := runtime.Stack(buf[:], false)
	idField := strings.Fields(strings.TrimPrefix(string(buf[:n]), "goroutine "))[0]
	id, err := strconv.Atoi(idField)
	if err != nil {
		panic(fmt.Sprintf("cannot get goroutine id: %v", err))
	}
	return id
}

  

2. 错误示范

var a []string
for i := 1; i < 5; i++ {
a = append(a, fmt.Sprintf("%d", i))
}
	for _, i := range a {
		fmt.Printf("-----%s---
", i)

		go func() {
			time.Sleep(time.Second * 4)
			testDomain(i)
		}()
	
	}

 打印发现i每次地址都是同一个

    协助每次先阻塞4秒

  4秒后 i的值是4, 这是协程中的方法testDomain开始工作,将i的值传给自己的形参

3. 正确示范

	for _, i := range a {
		fmt.Printf("-----%s---
", i)
		go func(a string) {
			//time.Sleep(time.Second * 4)
			testDomain(a)
		}(i)
	}

 这种操作会先将i的值传递给形参a,i的变化不会对testDomain方法的执行产生影响

 

4. 完整代码

package main

import (
	"fmt"
	"runtime"
	"strconv"
	"strings"
	"time"
)

func main() {
	var a []string
	for i := 1; i < 5; i++ {
		a = append(a, fmt.Sprintf("%d", i))
	}
	for _, i := range a {
		fmt.Printf("-----%s---
", i)
		go func(a string) {
			//time.Sleep(time.Second * 4)
			testDomain(a)
		}(i)

		go func() {
			time.Sleep(time.Second * 4)
			testDomain(i)
		}()
		fmt.Println(&i)
		time.Sleep(time.Second * 1)
	}

	time.Sleep(100 * time.Second)
}

func testDomain(ii string) {
	time.Sleep(time.Second * 4)
	fmt.Printf("pid: %d___point addr: %d___%s 
", GoID(), &ii, ii)
}

func GoID() int {
	var buf [64]byte
	n := runtime.Stack(buf[:], false)
	idField := strings.Fields(strings.TrimPrefix(string(buf[:n]), "goroutine "))[0]
	id, err := strconv.Atoi(idField)
	if err != nil {
		panic(fmt.Sprintf("cannot get goroutine id: %v", err))
	}
	return id
}

  

 

  

以上是关于golang range for循环中如何正确的给goroutine传参的主要内容,如果未能解决你的问题,请参考以下文章

Go语言自学系列 | golang for range循环

为啥正常的 for 循环允许为结构字段分配值,而 for range 在 Golang 中不起作用? [复制]

Golang 语言坑之for-range

如何在golang中获取随机数的样本? [关闭]

for循环使用range遍历数组尝试修改元素值的问题

Golang✔️走进 Go 语言✔️ 第十三课 range & map