gpt4 book ai didi

具有多种类型的协程和 channel

转载 作者:IT王子 更新时间:2023-10-29 01:23:39 27 4
gpt4 key购买 nike

我是 Go 的新手,正在尝试找出从 REST API 同时提取信息的最佳方法。目的是对 API 进行多个并发调用,每个调用返回不同类型的数据。

我目前有:

s := NewClient()
c1 := make(chan map[string]Service)
c2 := make(chan map[string]ServicePlan)
c3 := make(chan map[string]ServiceInstance)
c4 := make(chan map[string]ServiceBinding)
c5 := make(chan map[string]Organization)
c6 := make(chan map[string]Space)

go func() {
c1 <- GetServices(s)
}()

go func() {
c2 <- GetServicePlans(s)
}()

go func() {
c3 <- GetServiceInstances(s)
}()

go func() {
c4 <- GetServiceBindings(s)
}()

go func() {
c5 <- GetOrganizations(s)
}()

go func() {
c6 <- GetSpaces(s)
}()

services := <- c1
servicePlans := <- c2
serviceInstances := <- c3
serviceBindings := <- c4
orgs := <- c5
spaces := <- c6
// stitch all the data together later

但我想知道是否有更好的写法。

编辑:它仍然很丑陋,但将 channel 数量减少到一个:

c := make(chan interface{})

var (
services map[string]Service
servicePlans map[string]ServicePlan
serviceInstances map[string]ServiceInstance
serviceBindings map[string]ServiceBinding
orgs map[string]Organization
spaces map[string]Space
)

go func() {
c <- GetServices(s)
}()

go func() {
c <- GetServicePlans(s)
}()

go func() {
c <- GetServiceInstances(s)
}()

go func() {
c <- GetServiceBindings(s)
}()

go func() {
c <- GetOrganizations(s)
}()

go func() {
c <- GetSpaces(s)
}()

for i := 0; i < 6; i++ {
v := <-c
switch v := v.(type) {
case map[string]Service:
services = v
case map[string]ServicePlan:
servicePlans = v
case map[string]ServiceInstance:
serviceInstances = v
case map[string]ServiceBinding:
serviceBindings = v
case map[string]Organization:
orgs = v
case map[string]Space:
spaces = v
}
}

我仍然非常想要一种方法来执行此操作,这样我就不必硬编码循环需要运行 6 次。我实际上尝试制作一个要运行的函数列表,并以这种方式删除重复的 go func 调用,但由于所有函数都有不同的返回类型,我得到了所有类型不匹配错误,你可以要么使用 func(api) interface{} 来伪造它,因为这只会造成运行时 panic 。

最佳答案

当我看到这一点时,我认为我们可能将作业与完成混为一谈,从而为每种类型创建一个 channel 。

为每种类型创建一个用于分配的闭包和一个用于管理完成的 channel 可能会更简单。

例子:

s := NewClient()
c := make(chan bool)
// I don't really know the types here
var services services
var servicePlans servicePlans
var serviceInstances serviceInstances
var serviceBindings serviceInstances
var orgs orgs
var spaces spaces

go func() {
service = GetServices(s)
c <- true
}()

go func() {
servicePlans = GetServicePlans(s)
c <- true
}()

go func() {
serviceInstances = GetServiceInstances(s)
c <- true
}()

go func() {
serviceBindings = GetServiceBindings(s)
c <- true
}()

go func() {
orgs = GetOrganizations(s)
c <- true
}()

go func() {
spaces = GetSpaces(s)
c <- true
}()

for i = 0; i < 6; i++ {
<-c
}
// stitch all the data together later

Go 的作者预料到了这个用例,并提供了 sync.WaitGroup 使它更清楚一点 sync.WaitGroup Docs在它的下面是花哨的原子操作,它取代了 channel 同步。

例子:

s := NewClient()
// again, not sure of the types here
var services services
var servicePlans servicePlans
var serviceInstances serviceInstances
var serviceBindings serviceInstances
var orgs orgs
var spaces spaces

var wg sync.WaitGroup
wg.Add(6)

go func() {
service = GetServices(s)
wg.Done()
}()

go func() {
servicePlans = GetServicePlans(s)
wg.Done()
}()

go func() {
serviceInstances = GetServiceInstances(s)
wg.Done()
}()

go func() {
serviceBindings = GetServiceBindings(s)
wg.Done()
}()

go func() {
orgs = GetOrganizations(s)
wg.Done()
}()

go func() {
spaces = GetSpaces(s)
wg.Done()
}()

// blocks until all six complete
wg.Wait()
// stitch all the data together later

希望对您有所帮助。

关于具有多种类型的协程和 channel ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36870289/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com