为了账号安全,请及时绑定邮箱和手机立即绑定

从通道切片追加

从通道切片追加

Go
扬帆大鱼 2021-06-28 06:10:55
我想创建切片并添加从通道返回的值。以下是我尝试过但无法解决的代码。我必须发送切片的地址,但我无法弄清楚如何:(package mainimport "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 回答

?
呼如林

TA贡献1798条经验 获得超3个赞

由于两个(实际上是三个)原因,您的代码无法正常工作:

  1. append达到容量后立即返回一个新切片。因此,赋值 inappendInt将什么都不做。

  2. appendInt 同时运行,因此:

    • 只要appendInt没有消息main说它完成了, main不知道什么时候intSlice有你想要的所有值。

    • 你必须等待所有 goroutines 在结束时返回 main

问题一:修改函数中的切片

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

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

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


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()modify完成(完成时modify调用wg.Done())。如果您删除wg.Wait()呼叫,您将看到为什么不同步是一个问题。输出比较:

  • wg.Wait()[1 2 3 0 1 2 3 4 5 6 7 8 9]

  • 没有wg.Wait()[1 2 3]

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

传达新切片的一种好方法是使用通道。您不需要使用指针,并且可以进行同步。示例(播放):

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)

}


查看完整回答
反对 回复 2021-07-05
  • 1 回答
  • 0 关注
  • 184 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信