duanlu2935 2013-05-13 15:21
浏览 42
已采纳

与类型数组的通道通信

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 (
    "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("
 --- We timed out! --- 
")
            time.Sleep(5 * time.Second)

        }
    }
}

func Feeder2(w chan []string) {

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

    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'
",
        "SKY: Ariel Castro's Brothers Brand Him 'A Monster'
",
        "SKY: Astronaut Ends Space Mission With Bowie Song
",
        "SKY: Chinese Artist Films Violent Street Brawl
",
        "SKY: May Washout: Fortnight's Rainfall In One Day
",
        "SKY: Mother's Day Shooting: CCTV Shows Suspect
"}

    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)
}

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

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("
 --- We timed out! --- 
")
            time.Sleep(5 * time.Second)

        }
    }
}

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

    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'
",
        "SKY: Ariel Castro's Brothers Brand Him 'A Monster'
",
        "SKY: Astronaut Ends Space Mission With Bowie Song
",
        "SKY: Chinese Artist Films Violent Street Brawl
",
        "SKY: May Washout: Fortnight's Rainfall In One Day
",
        "SKY: Mother's Day Shooting: CCTV Shows Suspect
"}

    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)
}

Both of these versions wont work on playground website.

Thank you

  • 写回答

2条回答 默认 最新

  • duangan6133 2013-05-13 15:40
    关注

    Your problem is here:

    selection := []string{}
    for s := 0; s <= 3; s++ {
        selection[s] = 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 <= 3; s++ {
        selection[s] = 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 <= 3; s++ {
        selection = append(selection, headlines[randInt(0, len(headlines))])
    }
    

    append() will grow a slice as necessary.

    Link to relevant documentation

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 微信会员卡等级和折扣规则
  • ¥15 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗
  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分