来自 fanIn 示例的 golang 并发模式

Hok*_*sei 3 concurrency go

我正在关注 Rob Pike 去年 2012 年演讲中的 Go 并发模式示例(幻灯片来自此处:http : //talks.golang.org/2012/concurrency.slide#30)。

从示例“恢复序列”中,我不断收到错误消息:

prog.go:21: cannot use Message literal (type Message) as type string in send
prog.go:43: msg1.str undefined (type string has no field or method str)
prog.go:44: msg2.str undefined (type string has no field or method str)
prog.go:46: msg1.wait undefined (type string has no field or method wait)
prog.go:47: msg2.wait undefined (type string has no field or method wait)
Run Code Online (Sandbox Code Playgroud)

这是我的代码

type Message struct {
    str string
    wait chan bool  
}

func boring(msg string) <- chan string {
    c := make(chan string)
    waitForIt := make(chan bool)

    go func() {
        for i := 0; ; i++ {
            c <- Message{ fmt.Sprintf("%s: %d", msg, i), waitForIt }
            time.Sleep(time.Duration(rand.Intn(1e3)) * time.Millisecond)
            <-waitForIt
        }   
    }()
    return c    
}

func fanIn(input1, input2 <-chan string) <-chan string {
    c := make(chan string)
    go func() { for { c <- <-input1 } }()
    go func() { for { c <- <-input2 } }()
    return c
}

func main() {
    c := fanIn(boring("joe"), boring("ann"))

    for i := 0; i < 10; i++ {
        //fmt.Printf("You say %q\n", <-c)
        //fmt.Println(<-c)
        msg1 := <-c; fmt.Println(msg1.str)
        msg2 := <-c; fmt.Println(msg2.str)

        msg1.wait <- true
        msg2.wait <- true

        fmt.Println("--------------")
    }


    fmt.Println("Your boring, im leaving")
}
Run Code Online (Sandbox Code Playgroud)

和我的 Go 游乐场:http : //play.golang.org/p/6WQE0PUF7J

我究竟做错了什么?。

抱歉,我是 Go 的新手,我想学习它,因为我想将我所有的应用程序和工作应用程序从 node.js 迁移到 Go。

谢谢!

Sim*_*ead 5

YouTube 的演讲对此进行了更好的解释。

您的实际问题是,您已经完成了代码示例的一半。它从string频道开始- 然后转向Message频道。

我已经为你解决了这个问题。请参阅此游乐场链接:http : //play.golang.org/p/R60AJWzr0t

基本上,它现在变成了这个。注意所有的频道现在都是Message频道,而不是string频道。

type Message struct {
    str  string
    wait chan bool
}

func boring(msg string) <-chan Message {
    c := make(chan Message)
    waitForIt := make(chan bool)

    go func() {
        for i := 0; ; i++ {
            c <- Message{fmt.Sprintf("%s: %d", msg, i), waitForIt}
            time.Sleep(time.Duration(rand.Intn(1e3)) * time.Millisecond)
            <-waitForIt
        }
    }()
    return c
}

func fanIn(input1, input2 <-chan Message) <-chan Message {
    c := make(chan Message)
    go func() {
        for {
            c <- <-input1
        }
    }()
    go func() {
        for {
            c <- <-input2
        }
    }()
    return c
}

func main() {
    c := fanIn(boring("joe"), boring("ann"))

    for i := 0; i < 10; i++ {
        //fmt.Printf("You say %q\n", <-c)
        //fmt.Println(<-c)
        msg1 := <-c
        fmt.Println(msg1.str)
        msg2 := <-c
        fmt.Println(msg2.str)

        msg1.wait <- true
        msg2.wait <- true

        fmt.Println("--------------")
    }

    fmt.Println("Your boring, im leaving")
}
Run Code Online (Sandbox Code Playgroud)

你的错误意味着什么:

prog.go:21: 不能使用消息文字(消息类型)作为发送中的类型字符串

您正在第 21 行Messagestring通道上发送一个实例。将其更改为chan Message(以及当前为字符串通道的所有其他通道)。

prog.go:43: msg1.str 未定义(字符串类型没有字段或方法 str)

.. 其余的,是因为你有一个string频道,每次你从频道中弹出一些东西时,它是一个string- 而不是Message.