gpt4 book ai didi

go - 手动将chan转换/衰减到<-chan

转载 作者:行者123 更新时间:2023-12-01 22:45:45 26 4
gpt4 key购买 nike

我有一个功能:

func f(input interface{}) interface{} {
t := reflect.ChanOf(reflect.BothDir, <type that depends on input>)
c := reflect.MakeChan(t, ...)

// ... push things from input into c ...

return c
}
它创建一个通道,其元素类型取决于输入。它可以这样使用,但我希望它适用于任何类型,而不仅仅是int:
x := f(1).(<-chan int)
失败是因为我必须在函数内部使用reflect.BothDir(因为我正在 f内部向其发送值),因此实际类型为 chan <something>。我只希望此功能的用户看到频道的接收端。从 chan <something>返回之前,有什么方法可以将 <-chan <something>“投射”到 f吗?使用 <-chan interface{}的返回类型不是一种选择,因为从该类型转到 <-chan <something>将需要 f的用户创建另一个通道并将值手动推入该通道,但我希望 f用作单线。
编辑:
我也尝试使这尽可能通用,但是我想我必须更具体:
我正在尝试编写一个函数,该函数采用类型A的值的一个 slice ,并返回一个填充有该 slice 的值的通道。它打算在单元测试中使用,因此,我不必在乎必须使用反射,但是我确实在乎使测试尽可能简洁,这在我的特定情况下意味着重构由多个测试共享的初始化代码。确切的代码:
func gen(input interface{}) interface{} {
xs := reflect.ValueOf(input)

chanType := reflect.ChanOf(reflect.BothDir, xs.Type().Elem())
out := reflect.MakeChan(chanType, 0)

go func() {
for i := 0; i < xs.Len(); i++ {
x := xs.Index(i)
out.Send(i)
}

out.Close()
}

return out.Interface()
}
现在,如果我想测试一个函数 g(<-chan int),我以前必须在其中编写
values := <input generated by quick.check>

in := make(chan int)
go func() {
for _, value := range values {
in <- value
}
close(in)
}()
g(in)
我现在确实可以简单地打电话
g(gen(values).(chan int))
而且效果很好。这是因为 gen的返回类型是 chan int,它将隐式转换为 <-chan int。我的问题是关于这样的情况:
o := gen([]int{1, 1, 2, 3}).(chan int)
o <- 5 // You're not supposed to do that, sending to o is exclusive to the inside of the gen function
g(o)
我承认这种情况非常小众,即使Go无法提供防止这种情况的方法,我也会没事的,但是我主要是想知道如果我错过了某种语言的一部分,可以让我防止上述情况。

最佳答案

没有反射,您将使用(可能是隐式的)类型转换:

func sliceToChan(xs []int) <-chan int {
c := make(chan int)
// ...
return (<-chan int)(c) // or just `return c` for the implicit conversion
}
通过反射做同样的事情,即使用 Convert:
package main

import (
"fmt"
"reflect"
)

func main() {
x := sliceToChan([]int{1}).(<-chan int)
fmt.Println(cap(x))
}

func sliceToChan(input interface{}) interface{} {
xs := reflect.ValueOf(input)
elemType := xs.Type().Elem()

t := reflect.ChanOf(reflect.BothDir, elemType)
c := reflect.MakeChan(t, xs.Len())

for i := 0; i < xs.Len(); i++ {
x := xs.Index(i)
c.Send(x)
}

c.Close()

recvOnly := c.Convert(reflect.ChanOf(reflect.RecvDir, elemType))

return recvOnly.Interface()
}
在操场上尝试: https://play.golang.org/p/RDaAA_l9ghN

关于go - 手动将chan转换/衰减到<-chan,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63285586/

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