草庐IT

go - 与数组类型的 channel 通信

coder 2023-07-01 原文

我在这里尝试使用一个简单的模型来测试我对 go channels 的理解。在下面的小片段中,我尝试使用 2 个假新闻提要进程,将几个标题附加到本地数组,然后将其传递到数组字符串 channel 。在 main 中,我将这些数组传递回不同的打印过程。

编辑:我忘了提到这个问题。我的问题是我不断收到“索引超出边界”异常,我无法编译代码。

现在我用纯字符串变量尝试了同样的代码,它起作用了。

字符串数组代码:

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 网站上运行。

谢谢

最佳答案

你的问题在这里:

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

selection 是长度为 0 的 slice 。当您尝试将值设置为索引 0、1 和 2 时 - 这会导致运行时错误,因为没有分配空间他们。

初始化 slice 的首选方法是使用make():

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

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

另一种可能性是让运行时通过使用append()隐式增长你的 slice :

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

append() 将根据需要增加一个 slice 。

Link to relevant documentation

关于go - 与数组类型的 channel 通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16525612/

有关go - 与数组类型的 channel 通信的更多相关文章

  1. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  2. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  3. ruby - 将数组的内容转换为 int - 2

    我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]

  4. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  5. ruby - 通过 erb 模板输出 ruby​​ 数组 - 2

    我正在使用puppet为ruby​​程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby​​不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这

  6. ruby - 检查数组是否在增加 - 2

    这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife

  7. ruby - Infinity 和 NaN 的类型是什么? - 2

    我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串

  8. ruby - 检查方法参数的类型 - 2

    我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)

  9. ruby - 如果指定键的值在数组中相同,如何合并哈希 - 2

    我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat

  10. ruby - 在 Ruby 中用键盘诅咒数组浏览 - 2

    我正在尝试在Ruby中制作一个cli应用程序,它接受一个给定的数组,然后将其显示为一个列表,我可以使用箭头键浏览它。我觉得我已经在Ruby中看到一个库已经这样做了,但我记不起它的名字了。我正在尝试对soundcloud2000中的代码进行逆向工程做类似的事情,但他的代码与SoundcloudAPI的使用紧密耦合。我知道cursesgem,我正在考虑更抽象的东西。广告有没有人见过可以做到这一点的库或一些概念证明的Ruby代码可以做到这一点? 最佳答案 我不知道这是否是您正在寻找的,但也许您可以使用我的想法。由于我没有关于您要完成的工作

随机推荐