与数组类型的通道进行通信

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

communication with channels of type array

问题

我在这里尝试使用一个简单的模型来测试我对Go通道的理解。在下面的小片段中,我尝试使用一个假新闻源的2个进程,将几个标题附加到本地数组,然后将其传递给数组字符串通道。在主函数中,我将这些数组传递给另一个进程进行打印。

**编辑:**我忘了提到问题...我的问题是我一直收到“索引超出范围”的异常,无法编译代码。

现在我尝试使用普通的字符串变量运行相同的代码,它可以工作。

字符串数组代码:

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {

	/* initialization and assignment of channels */
	c := make(chan []string)
	p := make(chan []string)

	/* Pass created channels to Goroutines */
	go Feeder1(p)
	go Feeder2(p)
	go Consumer(c)

	for {
		select {
		case produced := <-p:
			c <- produced
		/*case <-time.After(6 * time.Second):
		return*/
		default:
			fmt.Printf("\n --- We timed out! --- \n")
			time.Sleep(5 * time.Second)

		}
	}
}

func Feeder2(w chan []string) {

	headlines := []string{
		"BBC: Speedboat victim 'doted on family'\n",
		"BBC: Syria rebel sarin claim downplayed\n",
		"BBC: German 'ex-Auschwitz guard' arrested\n",
		"BBC: Armless artist 'denied entry' to UK\n",
		"BBC: Bangladesh protest clashes kill 27\n",
		"BBC: Ex-Italian PM Giulio Andreotti dies\n"}

	for i := 0; ; i++ {
		selection := []string{}
		for s := 0; s <= 3; s++ {
			selection[s] = headlines[randInt(0, len(headlines))]
		}
		w <- selection
		time.Sleep(5 * time.Second)
	}
}

func Feeder1(w chan []string) {

	headlines := []string{
		"SKY: Deadly Virus Can 'Spread Between People'\n",
		"SKY: Ariel Castro's Brothers Brand Him 'A Monster'\n",
		"SKY: Astronaut Ends Space Mission With Bowie Song\n",
		"SKY: Chinese Artist Films Violent Street Brawl\n",
		"SKY: May Washout: Fortnight's Rainfall In One Day\n",
		"SKY: Mother's Day Shooting: CCTV Shows Suspect\n"}

	for i := 0; ; i++ {
		selection := []string{}
		for q := 0; q <= 3; q++ {
			selection[q] = headlines[randInt(0, len(headlines))]
		}
		w <- selection
		//randomTimeValue := randInt(5, 6)
		time.Sleep(2 * time.Second)
	}
}

func Consumer(n chan []string) {

	for {
		v := <-n
		for _, x := range v {
			fmt.Printf("Headline:\t%s", x)
		}
	}
}

func randInt(min int, max int) int {
	return min + rand.Intn(max-min)
}

之前运行的代码版本(这里没有数组):

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {

	/* initialization and assignment of channels */
	c := make(chan string)
	p := make(chan string)

	/* Pass created channels to Goroutines */
	go Feeder1(p)
	go Feeder2(p)
	go Consumer(c)

	for {
		select {

		case produced := <-p:
			c <- produced
		/*case <-time.After(6 * time.Second):
		return*/
		default:
			fmt.Printf("\n --- We timed out! --- \n")
			time.Sleep(5 * time.Second)

		}
	}
}

func Feeder2(w chan string) {
	headlines := []string{
		"BBC: Speedboat victim 'doted on family'\n",
		"BBC: Syria rebel sarin claim downplayed\n",
		"BBC: German 'ex-Auschwitz guard' arrested\n",
		"BBC: Armless artist 'denied entry' to UK\n",
		"BBC: Bangladesh protest clashes kill 27\n",
		"BBC: Ex-Italian PM Giulio Andreotti dies\n"}

	for i := 0; ; i++ {
		w <- headlines[randInt(0, len(headlines))]
		time.Sleep(5 * time.Second)
	}
}

func Feeder1(w chan string) {
	headlines := []string{
		"SKY: Deadly Virus Can 'Spread Between People'\n",
		"SKY: Ariel Castro's Brothers Brand Him 'A Monster'\n",
		"SKY: Astronaut Ends Space Mission With Bowie Song\n",
		"SKY: Chinese Artist Films Violent Street Brawl\n",
		"SKY: May Washout: Fortnight's Rainfall In One Day\n",
		"SKY: Mother's Day Shooting: CCTV Shows Suspect\n"}

	for i := 0; ; i++ {
		w <- headlines[randInt(0, len(headlines))]
		//randomTimeValue := randInt(5, 6)
		time.Sleep(2 * time.Second)
	}
}

func Consumer(n chan string) {

	for {
		v := <-n
		fmt.Printf("Headline:\t%s", v)
	}
}

func randInt(min int, max int) int {
	return min + rand.Intn(max-min)
}

这两个版本在playground网站上无法运行。

谢谢

英文:

I'm trying using a simple model here to test my understanding of go channels. in the small snippet below I try to use 2 processes of a fake news feed that append several headlines to a local array then pass that to the array string channel. in main I pass these array back to a different process for printing.

Edit: I forgot to mention the problem.. my issue is that I keep getting 'index out of boundary' exception and I'm unable to compile the code.

Now I tried this same code with plain string variables and it works.

string array code:

package main
import (
&quot;fmt&quot;
&quot;math/rand&quot;
&quot;time&quot;
)
func main() {
/* initialization and assignment of channels */
c := make(chan []string)
p := make(chan []string)
/* Pass created channels to Goroutines */
go Feeder1(p)
go Feeder2(p)
go Consumer(c)
for {
select {
case produced := &lt;-p:
c &lt;- produced
/*case &lt;-time.After(6 * time.Second):
return*/
default:
fmt.Printf(&quot;\n --- We timed out! --- \n&quot;)
time.Sleep(5 * time.Second)
}
}
}
func Feeder2(w chan []string) {
headlines := []string{
&quot;BBC: Speedboat victim &#39;doted on family&#39;\n&quot;,
&quot;BBC: Syria rebel sarin claim downplayed\n&quot;,
&quot;BBC: German &#39;ex-Auschwitz guard&#39; arrested\n&quot;,
&quot;BBC: Armless artist &#39;denied entry&#39; to UK\n&quot;,
&quot;BBC: Bangladesh protest clashes kill 27\n&quot;,
&quot;BBC: Ex-Italian PM Giulio Andreotti dies\n&quot;}
for i := 0; ; i++ {
selection := []string{}
for s := 0; s &lt;= 3; s++ {
selection
展开收缩
= headlines[randInt(0, len(headlines))] } w &lt;- selection time.Sleep(5 * time.Second) } } func Feeder1(w chan []string) { headlines := []string{ &quot;SKY: Deadly Virus Can &#39;Spread Between People&#39;\n&quot;, &quot;SKY: Ariel Castro&#39;s Brothers Brand Him &#39;A Monster&#39;\n&quot;, &quot;SKY: Astronaut Ends Space Mission With Bowie Song\n&quot;, &quot;SKY: Chinese Artist Films Violent Street Brawl\n&quot;, &quot;SKY: May Washout: Fortnight&#39;s Rainfall In One Day\n&quot;, &quot;SKY: Mother&#39;s Day Shooting: CCTV Shows Suspect\n&quot;} for i := 0; ; i++ { selection := []string{} for q := 0; q &lt;= 3; q++ { selection[q] = headlines[randInt(0, len(headlines))] } w &lt;- selection //randomTimeValue := randInt(5, 6) time.Sleep(2 * time.Second) } } func Consumer(n chan []string) { for { v := &lt;-n for _, x := range v { fmt.Printf(&quot;Headline:\t%s&quot;, x) } } } func randInt(min int, max int) int { return min + rand.Intn(max-min) }

The previously running version of the code (no arrays here):

package main
import (
&quot;fmt&quot;
&quot;math/rand&quot;
&quot;time&quot;
)
func main() {
/* initialization and assignment of channels */
c := make(chan string)
p := make(chan string)
/* Pass created channels to Goroutines */
go Feeder1(p)
go Feeder2(p)
go Consumer(c)
for {
select {
case produced := &lt;-p:
c &lt;- produced
/*case &lt;-time.After(6 * time.Second):
return*/
default:
fmt.Printf(&quot;\n --- We timed out! --- \n&quot;)
time.Sleep(5 * time.Second)
}
}
}
func Feeder2(w chan string) {
headlines := []string{
&quot;BBC: Speedboat victim &#39;doted on family&#39;\n&quot;,
&quot;BBC: Syria rebel sarin claim downplayed\n&quot;,
&quot;BBC: German &#39;ex-Auschwitz guard&#39; arrested\n&quot;,
&quot;BBC: Armless artist &#39;denied entry&#39; to UK\n&quot;,
&quot;BBC: Bangladesh protest clashes kill 27\n&quot;,
&quot;BBC: Ex-Italian PM Giulio Andreotti dies\n&quot;}
for i := 0; ; i++ {
w &lt;- headlines[randInt(0, len(headlines))]
time.Sleep(5 * time.Second)
}
}
func Feeder1(w chan string) {
headlines := []string{
&quot;SKY: Deadly Virus Can &#39;Spread Between People&#39;\n&quot;,
&quot;SKY: Ariel Castro&#39;s Brothers Brand Him &#39;A Monster&#39;\n&quot;,
&quot;SKY: Astronaut Ends Space Mission With Bowie Song\n&quot;,
&quot;SKY: Chinese Artist Films Violent Street Brawl\n&quot;,
&quot;SKY: May Washout: Fortnight&#39;s Rainfall In One Day\n&quot;,
&quot;SKY: Mother&#39;s Day Shooting: CCTV Shows Suspect\n&quot;}
for i := 0; ; i++ {
w &lt;- headlines[randInt(0, len(headlines))]
//randomTimeValue := randInt(5, 6)
time.Sleep(2 * time.Second)
}
}
func Consumer(n chan string) {
for {
v := &lt;-n
fmt.Printf(&quot;Headline:\t%s&quot;, v)
}
}
func randInt(min int, max int) int {
return min + rand.Intn(max-min)
}

Both of these versions wont work on playground website.

Thank you

答案1

得分: 1

你的问题在这里:

selection := []string{}
for s := 0; s <= 3; s++ {
selection
展开收缩
= headlines[randInt(0, len(headlines))] }

selection 是一个长度为0的切片。当你尝试给索引0、1和2设置值时,这会导致一个运行时错误,因为没有为它们分配空间。

初始化切片的首选方法是使用make()

selection := make([]string, 3, 3)
for s := 0; s <= 3; s++ {
selection
展开收缩
= headlines[randInt(0, len(headlines))] }

make()的第三个参数是容量。

另一种可能性是让运行时隐式地通过使用append()来增长切片:

selection := []string{}
for s := 0; s <= 3; s++ {
selection = append(selection, headlines[randInt(0, len(headlines))])
}

append()会根据需要增长切片。

相关文档链接

英文:

Your problem is here:

selection := []string{}
for s := 0; s &lt;= 3; s++ {
selection
展开收缩
= headlines[randInt(0, len(headlines))] }

selection is a slice of length 0. When you try to set values to indexes 0, 1 and 2 - that's causing a runtime error because there's no space allocated for them.

The preferred way to initialize a slice is using make():

selection := make([]string, 3, 3)
for s := 0; s &lt;= 3; s++ {
selection
展开收缩
= headlines[randInt(0, len(headlines))] }

The third argument to make() is capacity.

Another possibility is to let the runtime grow your slice implicitly by using append():

selection := []string{}
for s := 0; s &lt;= 3; s++ {
selection = append(selection, headlines[randInt(0, len(headlines))])
}

append() will grow a slice as necessary.

Link to relevant documentation

答案2

得分: 0

你的字符串“array”代码使用的是切片,而不是数组。
你正在执行selection[q] = something,但是你的切片长度为0,这应该会引发错误。要么:创建长度不为0的正确切片,要么使用数组。

(我个人更喜欢playground代码)。

英文:

Your string "array" code is using slices, not arrays.
You are doing selection[q] = something, but your slice
has length 0, that should panic. Either: Make proper
slice with len != 0 or do use an array.

(I personally prefer playground code).

huangapple
  • 本文由 发表于 2013年5月13日 23:21:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/16525612.html
匿名

发表评论

匿名网友

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

确定