Refactor code to use a single channel in an idiomatic way

隐身守侯 提交于 2020-12-13 03:13:10

问题


I have the following code:

package main

import (
    "fmt"
    "time"
)

type Response struct {
    Data   string
    Status int
}

func main() {
    var rc [10]chan Response
    for i := 0; i < 10; i++ {
        rc[i] = make(chan Response)
    }
    var responses []Response

    for i := 0; i < 10; i++ {
        go func(c chan<- Response, n int) {
            c <- GetData(n)
            close(c)
        }(rc[i], i)
    }

    for _, resp := range rc {
        responses = append(responses, <-resp)
    }

    for _, item := range responses {
        fmt.Printf("%+v\n", item)
    }
}

func GetData(n int) Response {
    time.Sleep(time.Second * 5)
    return Response{
        Data:   "adfdafcssdf4343t43gf3jn4jknon239nwcwuincs",
        Status: n,
    }
}

Can you tell me which would be the right way to accomplish the same goal but using a single channel?


回答1:


Since you can write different array and slice elements concurrently, you don't need any channels in your case. For details, see Can I concurrently write different slice elements.

Just launch your goroutines, and have them write in the appropriate array (or slice) elements. Use a sync.WaitGroup to wait for all to complete:

wg := &sync.WaitGroup{}
var responses [10]Response
for i := range responses {
    wg.Add(1)
    go func(n int) {
        defer wg.Done()
        responses[n] = GetData(n)
    }(i)
}

wg.Wait()
for _, item := range responses {
    fmt.Printf("%+v\n", item)
}

This outputs the same as your code. Try it on the Go Playground.

Also see related: How to collect values from N goroutines executed in a specific order?



来源:https://stackoverflow.com/questions/64838433/refactor-code-to-use-a-single-channel-in-an-idiomatic-way

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!