Golang并发模式:来自fanIn示例的代码部分。

huangapple go评论102阅读模式
英文:

golang concurrency pattern from fanIn example

问题

我正在遵循Rob Pike在2012年的演讲中介绍的Go并发模式示例(幻灯片链接:http://talks.golang.org/2012/concurrency.slide#30)。

从"Restoring Sequence"这个示例中,我一直遇到一个错误:

prog.go:21: 无法将Message字面量(类型为Message)作为send中的string类型
prog.go:43: msg1.str未定义(string类型没有str字段或方法)
prog.go:44: msg2.str未定义(string类型没有str字段或方法)
prog.go:46: msg1.wait未定义(string类型没有wait字段或方法)
prog.go:47: msg2.wait未定义(string类型没有wait字段或方法)

以下是我的代码:

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, I'm leaving")
}

这是我的Go Playground链接:http://play.golang.org/p/6WQE0PUF7J

我做错了什么?

抱歉,我刚接触Go,我想学习它,因为我想将所有的应用程序和工作应用程序从Node.js迁移到Go。

谢谢!

英文:

I am following Rob Pike's Go concurrency pattern examples from his talk from last 2012 (the the slides are from here: http://talks.golang.org/2012/concurrency.slide#30 ).

From the example "Restoring Sequence", I keep getting an error:

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)

Here is my code

type Message struct {
	str string
	wait chan bool	
}

func boring(msg string) &lt;- chan string {
	c := make(chan string)
	waitForIt := make(chan bool)
	
	go func() {
		for i := 0; ; i++ {
			c &lt;- Message{ fmt.Sprintf(&quot;%s: %d&quot;, msg, i), waitForIt }
			time.Sleep(time.Duration(rand.Intn(1e3)) * time.Millisecond)
			&lt;-waitForIt
		}	
	}()
	return c	
}

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

func main() {
	c := fanIn(boring(&quot;joe&quot;), boring(&quot;ann&quot;))
	
	for i := 0; i &lt; 10; i++ {
		//fmt.Printf(&quot;You say %q\n&quot;, &lt;-c)
		//fmt.Println(&lt;-c)
		msg1 := &lt;-c; fmt.Println(msg1.str)
		msg2 := &lt;-c; fmt.Println(msg2.str)
		
		msg1.wait &lt;- true
		msg2.wait &lt;- true
	
		fmt.Println(&quot;--------------&quot;)
	}
		
	
	fmt.Println(&quot;Your boring, im leaving&quot;)
}

and my Go playground: http://play.golang.org/p/6WQE0PUF7J

What am I doing wrong?.

Sorry I'm new to Go and I would like to learn it because I want to move all of my apps and work apps from node.js to Go.

Thank you!

答案1

得分: 6

YouTube的讲解会更好地解释这个问题。

你实际的问题是,你在代码示例的中间部分。它开始是string类型的通道,然后转换为Message类型的通道。

我已经为你修复了这个问题。请查看这个playground链接: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")
}

你的错误的含义:

> prog.go:21: cannot use Message literal (type Message) as type string in send

在第21行,你正在将Message实例发送到string类型的通道上。将其更改为chan Message(以及所有当前为字符串通道的其他通道)。

> prog.go:43: msg1.str undefined (type string has no field or method str)

..以及其他错误,是因为你有一个string类型的通道,每次从通道中取出的是一个string,而不是Message

英文:

The YouTube talk explains it a bit better.

What your actual problem is, is that you're half-way through the code sample. It starts off with string channels - then moves on to Message channels.

I have fixed this up for you. See this playground link: http://play.golang.org/p/R60AJWzr0t

Basically, it becomes this now. Notice how all of the channels are now Message channels, not string channels.

type Message struct {
str  string
wait chan bool
}
func boring(msg string) &lt;-chan Message {
c := make(chan Message)
waitForIt := make(chan bool)
go func() {
for i := 0; ; i++ {
c &lt;- Message{fmt.Sprintf(&quot;%s: %d&quot;, msg, i), waitForIt}
time.Sleep(time.Duration(rand.Intn(1e3)) * time.Millisecond)
&lt;-waitForIt
}
}()
return c
}
func fanIn(input1, input2 &lt;-chan Message) &lt;-chan Message {
c := make(chan Message)
go func() {
for {
c &lt;- &lt;-input1
}
}()
go func() {
for {
c &lt;- &lt;-input2
}
}()
return c
}
func main() {
c := fanIn(boring(&quot;joe&quot;), boring(&quot;ann&quot;))
for i := 0; i &lt; 10; i++ {
//fmt.Printf(&quot;You say %q\n&quot;, &lt;-c)
//fmt.Println(&lt;-c)
msg1 := &lt;-c
fmt.Println(msg1.str)
msg2 := &lt;-c
fmt.Println(msg2.str)
msg1.wait &lt;- true
msg2.wait &lt;- true
fmt.Println(&quot;--------------&quot;)
}
fmt.Println(&quot;Your boring, im leaving&quot;)
}

What your errors mean:

> prog.go:21: cannot use Message literal (type Message) as type string in send

You're sending a Message instance on the string channel on line 21. Change it to chan Message (and all of the other channels that are string channels currently).

> prog.go:43: msg1.str undefined (type string has no field or method str)

.. and the rest, are because you have a string channel, and each time you pop something from the channel, its a string - not a Message.

huangapple
  • 本文由 发表于 2014年6月30日 10:54:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/24482372.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定