草庐IT

go - 从 channel 附加 slice

coder 2023-06-27 原文

我想创建 slice 并添加从 channel 返回的值。 以下是我尝试但无法解决的代码。

我必须发送 slice 的地址,但我不知道如何:(

package main

import "fmt"
import "time"

func sendvalues(cs chan int){
    for i:=0;i<10;i++{
        cs<-i   
    }   
}

func appendInt(cs chan int, aINt []int)[]*int{
    for {
        select {
        case i := <-cs:
            aINt = append(aINt,i)//append returns new type right ?
            fmt.Println("slice",aINt)
        }   
    }   
}



func main() {
    cs := make(chan int)
    intSlice := make([]int, 0,10)

    fmt.Println("Before",intSlice)
    go sendvalues(cs)
    go appendInt(cs,intSlice)// I have to pass address here

    time.Sleep(999*999999)
    fmt.Println("After",intSlice)
}

最佳答案

您的代码无法工作有两个(实际上是三个)原因:

  1. append 在达到容量后立即返回一个新 slice 。 因此,appendInt 中的赋值不会执行任何操作。

  2. appendInt 并发运行,因此:

    • 只要 appendInt 不向 main 发送消息表示它已完成, main 不知道什么时候 intSlice 有你想要的所有值。
    • 您必须等待所有 goroutines 在 main 结束时返回

问题一:在函数中修改 slice

您可能知道在 Go 中,您传递给函数的每个值都会被复制。引用值, 例如 slice ,也被复制,但内部有指针,然后指向原始内存位置。这意味着您可以在函数中修改 slice 的元素。你什么 不能做的是用一个新的 slice 重新分配这个值,因为内部指针会指向不同的地方。 为此你需要指导。示例 ( Play ):

func modify(s *[]int) {
    for i:=0; i < 10; i++ {
        *s = append(*s, i)
    }
}

func main() {
    s := []int{1,2,3}
    modify(&s)
    fmt.Println(s)
}

问题2:同步goroutines

要等待启动的 goroutines,您可以使用 sync.WaitGroup .示例 ( Play ):

func modify(wg *sync.WaitGroup, s *[]int) {
    defer wg.Done()
    for i:=0; i < 10; i++ {
        *s = append(*s, i)
    }
}

func main() {
    wg := &sync.WaitGroup{}
    s := []int{1,2,3}

    wg.Add(1)
    go modify(wg, &s)

    wg.Wait()
    fmt.Println(s)
}

上面的例子等待(使用wg.Wait())修改完成 (修改 完成后调用wg.Done())。如果删除 wg.Wait() 调用,您将 看看为什么不同步是个问题。输出比较:

  • 使用 wg.Wait():[1 2 3 0 1 2 3 4 5 6 7 8 9]
  • 没有 wg.Wait():[1 2 3]

主 goroutine 比 modify goroutine 更早返回,这就是为什么你永远不会 查看修改后的结果。因此同步是绝对必要的

传达新 slice 的一种好方法是使用 channel 。你不需要 使用指针,你就会有同步。示例 ( Play ):

func modify(res chan []int) {
    s := []int{}
    for i:=0; i < 10; i++ {
        s = append(s, i)
    }
    res <- s
}

func main() {
    c := make(chan []int)
    go modify(c)

    s := <-c
    fmt.Println(s)
}

关于go - 从 channel 附加 slice ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19818878/

有关go - 从 channel 附加 slice的更多相关文章

  1. ruby-on-rails - 简单的 Ruby on Rails 问题——如何将评论附加到用户和文章? - 2

    我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。

  2. ruby-on-rails - Textmate 'Go to symbol' 相当于 Vim - 2

    在Railcasts上,我注意到一个非常有趣的功能“转到符号”窗口。它像Command-T一样工作,但显示当前文件中可用的类和方法。如何在vim中获取它? 最佳答案 尝试:helptags有各种程序和脚本可以生成标记文件。此外,标记文件格式非常简单,因此很容易将sed(1)或类似的脚本组合在一起,无论您使用何种语言,它们都可以生成标记文件。轻松获取标记文件(除了下载生成器之外)的关键在于格式化样式而不是实际解析语法。 关于ruby-on-rails-Textmate'Gotosymbol

  3. ruby-on-rails - ruby:将数组的每个元素用附加引号引起来 - 2

    我有以下字符串:a="001;Barbara;122"我拆分成字符串数组:names=a.split(";")names=["001","Barbara","122"]我应该怎么做才能将每​​个元素另外用''引号括起来?结果应该是names=["'001'","'Barbara'","'122'"]我知道这听起来很奇怪,但我需要它在ruby​​onrails中进行数据库查询。出于某种原因,如果我的名字在“”引号中,我将无法访问数据库记录。我在数据库中确实有mk1==0006但rails不想以某种方式访问​​它。但是,它确实访问1222。sql="SELECTmk1,mk2,pk1,pk

  4. ruby - 如何在 Ruby 中创建数字列表并将其反向附加到它 - 2

    给定一个最小整数和最大整数,我想创建一个数组,它从最小值到最大值以二为单位计数,然后倒退(再次以二为单位,重复最大数)。例如,如果最小数是1,最大数是9,我想要[1,3,5,7,9,9,7,5,3,1].我试图尽可能简洁,这就是我使用单行代码的原因。在Python中,我会这样做:range(1,10,2)+range(9,0,-2)在我刚刚开始学习的Ruby中,到目前为止我所想到的是:(1..9).inject([]){|r,num|num%2==1?r这行得通,但我知道必须有更好的方法。这是什么? 最佳答案 (1..9).step

  5. ruby - 为什么 `<<` 附加到 Ruby 字符串而 `+=` 不附加? - 2

    这个问题在这里已经有了答案:ArestringsmutableinRuby?(3个答案)WhenpassingaRubyarrayasanargument,whydoes`(2个答案)关闭8年前。我正在学习教程,我想了解为什么会出现以下情况:original_string="Hello,"hi=original_stringthere="World"hi+=thereassert_equal"Hello,",original_stringoriginal_string="Hello,"hi=original_stringthere="World"hi为什么+=对original_str

  6. ruby - 给定一个 Ruby 元类,我如何获取它所附加的实例? - 2

    这是问题“GivenaninstanceofaRubyobject,howdoIgetitsmetaclass?”的反面您可以在默认的to_s输出中看到附加元类或单例类的对象的表示:s="hello"s_meta=class"#>"classC;endc_meta=class"#"是否有可能实现一个方法Class.attached来返回这个对象(如果接收者是一个普通类,则返回nil)?s_meta.attached#=>sc_meta.attached#=>CC.attached#=>nil 最佳答案 有一个丑陋的(但有效的)黑客,

  7. ruby - 附加具有唯一值的收集数组 - 2

    所以我有一个由collect构建的数组。@a=Relation.where(part:"v04")@relations=@a.collect{|x|x.car}构建..=>["f03","f04"]@a=Relation.where(part:"v03")@relations=@a.collect{|x|x.car}构建..=>["f01","f03"]我想要的是追加收集,这样我就可以从v03和v04构建一个数组,它看起来像这样。=>["f03","f04","f01","f03"]然后只保留唯一值,所以它看起来像这样。=>["f03","f04","f01"]取出f03,因为它列出了

  8. ruby-on-rails - 用于 Ruby 的 vim 中的全局 "Go to definition"? - 2

    自97年以来我一直在使用vi/vim进行各种快速编辑和管理任务,但最近才考虑使用它来替换Netbeans作为我选择的ruby​​编辑器。我发现一件事在Netbeans和Eclipse中非常有用的是Ctrl+Click“转到定义”功能,您可以在其中按住Ctrl键并单击一个类或方法,然后它将带您了解定义。现在,我玩过丰富的ctags和rails.vim,而且很接近,但没有雪茄。这就是我想要的:默认情况下在Netbeans和Eclipse中,您可以在本地rails中按住ctrl并单击本地方法或类项目,但你也可以ctrl+click定义在gems或用Ruby编写的系统库。以Netbeans为例

  9. ruby-on-rails - 冒号前缀和附加之间的区别(:item vs item:) - 2

    在ruby​​中追加和前置冒号有什么区别?例子:#Inrailsyouoftenhavethingslikethis:has_many:models,dependent::destroy为什么dependent:有一个冒号,而:models和:destroy有一个冒号?有什么区别? 最佳答案 这是Ruby1.9中的新语法,用于定义散列中作为键的符号。前置和附加的:都定义了一个symbol,但后者仅在散列初始化期间有效。你可以想到一个symbol作为轻量级字符串常量。相当于:dependent=>:destroy在1.9之前,散列是使

  10. css - 使用 Compass/Sass 删除附加到 Sprite 文件名的随机字符串 - 2

    我最近一直在使用Compass和Sass来做一些CSSspriting,因为它非常有用。但是,文件名总是附加一个随机字符串。例如。图标-s5eb424578c.png。而且我不希望附加这个随机字符串,因为这意味着每次发生更改时我都需要上传新的CSS文件和新的Sprite图像。那么,有人知道Compassgem目录中哪个Ruby或其他配置文件附加了这个随机字符串吗?然后我可以只注释掉那个位的代码。除非我缺少官方变量,否则我可以在Compass中设置以告诉它我不想附加此字符串?提前感谢您对此提供的任何帮助。 最佳答案 尝试将这些行添加到

随机推荐