gpt4 book ai didi

go - 将 channel 的所有元素消耗到 slice 中

转载 作者:IT老高 更新时间:2023-10-28 13:10:41 24 4
gpt4 key购买 nike

如何从 channel 消耗的所有元素中构造一个 slice (如 Python 的 list 那样)?我可以使用这个辅助函数:

func ToSlice(c chan int) []int {
s := make([]int, 0)
for i := range c {
s = append(s, i)
}
return s
}

但由于 lack of generics ,我必须为每种类型都写,不是吗?是否有实现此功能的内置函数?如果没有,如何避免为我使用的每种类型复制和粘贴上述代码?

最佳答案

如果您的代码中只有少数几个实例需要转换,那么将这 7 行代码复制几次(或者甚至将其内联到使用它的地方,将其减少到 4 行代码)绝对没有错并且可能是最易读的解决方案)。

如果您确实在很多类型的 channel 和 slice 之间进行了转换,并且想要一些通用的东西,那么您可以通过反射来做到这一点,但代价是丑陋和 ChanToSlice 调用点缺少静态类型。

这里有完整的示例代码,展示了如何使用反射来解决这个问题,并演示了它适用于 int channel 。

package main

import (
"fmt"
"reflect"
)

// ChanToSlice reads all data from ch (which must be a chan), returning a
// slice of the data. If ch is a 'T chan' then the return value is of type
// []T inside the returned interface.
// A typical call would be sl := ChanToSlice(ch).([]int)
func ChanToSlice(ch interface{}) interface{} {
chv := reflect.ValueOf(ch)
slv := reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(ch).Elem()), 0, 0)
for {
v, ok := chv.Recv()
if !ok {
return slv.Interface()
}
slv = reflect.Append(slv, v)
}
}

func main() {
ch := make(chan int)
go func() {
for i := 0; i < 10; i++ {
ch <- i
}
close(ch)
}()
sl := ChanToSlice(ch).([]int)
fmt.Println(sl)
}

关于go - 将 channel 的所有元素消耗到 slice 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20385464/

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