动态创建goroutine的最佳方法是什么?

动态创建goroutine的最佳方法是什么?,go,Go,抱歉,如果这是一个新手问题,但我是新手;)。我有一本书。如何动态创建goroutine?我在操场上的第一个集合按预期工作,但我的第二个集合对每个值返回“11”。我可以通过取消第38行的注释来解决这个问题,但这看起来有点像是一个黑客。有没有更喜欢的方法来动态创建我的goroutine package main import ( "fmt" "log" "time" ) func myFunc(i int) int { return i } func first

抱歉,如果这是一个新手问题,但我是新手;)。我有一本书。如何动态创建goroutine?我在操场上的第一个集合按预期工作,但我的第二个集合对每个值返回“11”。我可以通过取消第38行的注释来解决这个问题,但这看起来有点像是一个黑客。有没有更喜欢的方法来动态创建我的goroutine

package main

import (
    "fmt"
    "log"
    "time"
)

func myFunc(i int) int {
    return i
}

func first() {
    firstChannel := make(chan int)
    go func() { firstChannel <- myFunc(0) }()
    go func() { firstChannel <- myFunc(1) }()
    go func() { firstChannel <- myFunc(2) }()
    go func() { firstChannel <- myFunc(3) }()
    go func() { firstChannel <- myFunc(4) }()
    go func() { firstChannel <- myFunc(5) }()
    go func() { firstChannel <- myFunc(6) }()
    go func() { firstChannel <- myFunc(7) }()
    go func() { firstChannel <- myFunc(8) }()
    go func() { firstChannel <- myFunc(9) }()
    go func() { firstChannel <- myFunc(10) }()

    for k := 0; k < 11; k++ {
        select {
        case result := <-firstChannel:
            log.Println(result)
        }
    }
}
func second() {
    secondChannel := make(chan int)
    for j := 0; j < 11; j++ {
        go func() { secondChannel <- myFunc(j) }()
        //time.Sleep(1*time.Millisecond)
    }
    for k := 0; k < 11; k++ {
        select {
        case result := <-secondChannel:
            log.Println(result)
        }
    }
}

func main() {
    fmt.Println("First set------------------")
    first()
    time.Sleep(1 * time.Second)
    fmt.Println("Second set------------------")
    second()
}

函数文字是闭包:它们可能引用在中定义的变量 周围的功能。然后,这些变量在 围绕函数和函数文字,它们作为 只要它们是可访问的

在并发使用闭包时可能会出现一些混乱

要在每个闭包启动时将v的当前值绑定到它,一个 每次迭代都必须修改内部循环以创建新变量。 一种方法是将变量作为参数传递给闭包

更简单的方法是使用声明创建一个新变量 看起来很奇怪,但在围棋中效果很好的风格

使用
j:=j
。比如说,

package main

import (
    "fmt"
    "log"
    "time"
)

func myFunc(i int) int {
    return i
}

func first() {
    firstChannel := make(chan int)
    go func() { firstChannel <- myFunc(0) }()
    go func() { firstChannel <- myFunc(1) }()
    go func() { firstChannel <- myFunc(2) }()
    go func() { firstChannel <- myFunc(3) }()
    go func() { firstChannel <- myFunc(4) }()
    go func() { firstChannel <- myFunc(5) }()
    go func() { firstChannel <- myFunc(6) }()
    go func() { firstChannel <- myFunc(7) }()
    go func() { firstChannel <- myFunc(8) }()
    go func() { firstChannel <- myFunc(9) }()
    go func() { firstChannel <- myFunc(10) }()

    for k := 0; k < 11; k++ {
        select {
        case result := <-firstChannel:
            log.Println(result)
        }
    }
}
func second() {
    secondChannel := make(chan int)
    for j := 0; j < 11; j++ {
        j := j
        go func() { secondChannel <- myFunc(j) }()
        //time.Sleep(1*time.Millisecond)
    }
    for k := 0; k < 11; k++ {
        select {
        case result := <-secondChannel:
            log.Println(result)
        }
    }
}

func main() {
    fmt.Println("First set------------------")
    first()
    time.Sleep(1 * time.Second)
    fmt.Println("Second set------------------")
    second()
}
主程序包
进口(
“fmt”
“日志”
“时间”
)
func myFunc(i int)int{
返回i
}
func first(){
第一个通道:=制造(通道内部)
使用循环转到func(){firstChannel

for j := 0; j < 11; j++ {
    go func() { secondChannel <- myFunc(j) }()
    //time.Sleep(1*time.Millisecond)
}
现在,由循环中的func()创建的闭包引用
arg
变量,该变量对于每个迭代都是独立的

也可以通过将变量复制到func()的参数来传递:

j:=0;j<11;j++{
go func(arg int){secondChannel我真的很讨厌在两个非常可靠的答案之间进行选择,所以我纯粹基于时间……看起来你只是被@PeterSO打败了一点点。我给了你一个高分。谢谢!我喜欢将它作为arg传递,因为它清楚地表明内部变量与
func
literal相关,而不是让读者看一个潜在的神秘宣言。 First set------------------ 2009/11/10 23:00:00 0 2009/11/10 23:00:00 1 2009/11/10 23:00:00 2 2009/11/10 23:00:00 3 2009/11/10 23:00:00 4 2009/11/10 23:00:00 5 2009/11/10 23:00:00 6 2009/11/10 23:00:00 7 2009/11/10 23:00:00 8 2009/11/10 23:00:00 9 2009/11/10 23:00:00 10 Second set------------------ 2009/11/10 23:00:01 0 2009/11/10 23:00:01 1 2009/11/10 23:00:01 2 2009/11/10 23:00:01 3 2009/11/10 23:00:01 4 2009/11/10 23:00:01 5 2009/11/10 23:00:01 6 2009/11/10 23:00:01 7 2009/11/10 23:00:01 8 2009/11/10 23:00:01 9 2009/11/10 23:00:01 1
for j := 0; j < 11; j++ {
    go func() { secondChannel <- myFunc(j) }()
    //time.Sleep(1*time.Millisecond)
}
for j := 0; j < 11; j++ {
    arg := j
    go func() { secondChannel <- myFunc(arg) }()
    //time.Sleep(1*time.Millisecond)
}
for j := 0; j < 11; j++ {
    go func(arg int) { secondChannel <- myFunc(arg) }(j)
    //time.Sleep(1*time.Millisecond)
}