Go 1.16中如何便捷管理不同结构体的并发获取结果
适用于Go 1.16的并发结果收集方案
针对你的场景,推荐用接口+任务封装的方式实现,既保证类型安全,又能充分利用并发特性,还能避免聚合结构体冗余、反射类型转换的问题。
核心思路
- 定义一个通用的
Result标记接口,作为所有返回结构体的统一类型载体; - 为每个业务类型(
Person/Pet)封装对应的任务逻辑,实现统一的执行方法; - 批量启动所有任务的goroutine,将结果统一发送到通道中,最后遍历处理。
具体实现代码
第一步:定义通用接口和任务封装
import "sync" // Result 标记接口,用于统一所有业务结构体类型 type Result interface{} // 封装Person查询任务的函数 func wrapPersonQuery(id int) func() Result { return func() Result { return <-GetPerson(id) } } // 封装Pet查询任务的函数 func wrapPetQuery(id int) func() Result { return func() Result { return <-GetPet(id) } }
第二步:并发执行任务并收集结果
func main() { // 构造所有需要执行的任务列表 var taskFuncs []func() Result // 添加Person查询任务 taskFuncs = append(taskFuncs, wrapPersonQuery(1), wrapPersonQuery(2)) // 添加Pet查询任务 taskFuncs = append(taskFuncs, wrapPetQuery(3), wrapPetQuery(4)) // 初始化结果通道和WaitGroup resultCh := make(chan Result, len(taskFuncs)) var wg sync.WaitGroup wg.Add(len(taskFuncs)) // 并发启动所有任务 for _, fn := range taskFuncs { fn := fn // 闭包捕获当前循环变量,避免变量复用问题 go func() { defer wg.Done() resultCh <- fn() }() } // 所有任务完成后关闭结果通道 go func() { wg.Wait() close(resultCh) }() // 遍历处理所有结果 for res := range resultCh { switch v := res.(type) { case Person: // 处理Person类型结果,比如打印或存入统一存储 println("Person:", v.Name, v.Age) case Pet: // 处理Pet类型结果 println("Pet:", v.Name, v.Type) } } }
方案优势
- 类型安全:完全基于编译时检查,避免反射带来的类型转换错误和性能损耗;
- 并发高效:所有任务同时启动,充分利用Go的goroutine并发能力;
- 扩展性强:新增业务类型时,只需要添加对应的包装函数即可,无需修改核心收集逻辑;
- 代码简洁:避免了聚合结构体的参数冗余问题,任务定义清晰。
进阶:面向对象风格的任务封装
如果需要更清晰的任务职责划分,也可以用结构体封装任务:
// PersonTask 封装Person的查询任务 type PersonTask struct { ID int } // Execute 执行任务并返回结果 func (t PersonTask) Execute() Result { return <-GetPerson(t.ID) } // PetTask 封装Pet的查询任务 type PetTask struct { ID int } // Execute 执行任务并返回结果 func (t PetTask) Execute() Result { return <-GetPet(t.ID) } // 执行逻辑 func main() { var tasks []interface { Execute() Result } tasks = append(tasks, PersonTask{ID: 1}, PersonTask{ID: 2}) tasks = append(tasks, PetTask{ID: 3}, PetTask{ID: 4}) // 后续并发执行和结果收集逻辑与之前一致,仅遍历对象改为调用task.Execute() }
这个方案更适合任务带有额外参数或复杂逻辑的场景,代码可读性更强。
内容的提问来源于stack exchange,提问作者DubDub
相关产品推荐
相关产品推荐

