调用接受 "chan interface{}" 的函数
invoke function which accept "chan interface{}"
对于投反对票的人 - 它确实有一个合理的答案,即反思(见下文)。
我想创建一个通用函数,我可以将任何通道传递给它,它会告诉我它的容量已满多少。我发现必须将频道转换为 "chan interface{}" 很烦人。
我的问题是,对于下面的函数 foo
,我可以向它传递一个字符串,这很好。 Go 接受它作为接口{}。为什么它对频道的行为不同?我可以创建一个接受通用 chan interface{}
的函数吗?
func testFoo() {
str := "anything"
foo(str) //This is fine.
aChan := make(chan string, 10)
//This line doesn't compile. Can I avoid casting to chan interface{}?
CheckChanLen(aChan)
}
func foo(obj interface{}) {}
func CheckChanLen(aChan chan interface{}) {
chanCap := cap(aChan)
chanLen := len(aChan)
fmt.Printf("len:%d cap:%d", chanLen, chanCap)
}
简答:没有。
chan interface{}
是与 interface{}
不同的类型。
interface{}
是所有类型的包罗万象,但是 chan interface{}
NOT 是所有 chan
类型的包罗万象。
泛型会带来这种能力,但它们不在 go 语言中 (yet)。
如果您需要做的只是检查频道 capacity/length,您可以像这样使用 reflect
包:
import "reflect"
func CheckChanLen(aChan interface{}) {
rv := reflect.ValueOf(aChan)
if rk := rv.Kind(); rk != reflect.Chan {
panic("expecting type: 'chan ...' instead got: " + rk.String())
}
chanCap := rv.Cap()
chanLen := rv.Len()
fmt.Printf("len:%d cap:%d\n", chanLen, chanCap)
}
对于投反对票的人 - 它确实有一个合理的答案,即反思(见下文)。
我想创建一个通用函数,我可以将任何通道传递给它,它会告诉我它的容量已满多少。我发现必须将频道转换为 "chan interface{}" 很烦人。
我的问题是,对于下面的函数 foo
,我可以向它传递一个字符串,这很好。 Go 接受它作为接口{}。为什么它对频道的行为不同?我可以创建一个接受通用 chan interface{}
的函数吗?
func testFoo() {
str := "anything"
foo(str) //This is fine.
aChan := make(chan string, 10)
//This line doesn't compile. Can I avoid casting to chan interface{}?
CheckChanLen(aChan)
}
func foo(obj interface{}) {}
func CheckChanLen(aChan chan interface{}) {
chanCap := cap(aChan)
chanLen := len(aChan)
fmt.Printf("len:%d cap:%d", chanLen, chanCap)
}
简答:没有。
chan interface{}
是与 interface{}
不同的类型。
interface{}
是所有类型的包罗万象,但是 chan interface{}
NOT 是所有 chan
类型的包罗万象。
泛型会带来这种能力,但它们不在 go 语言中 (yet)。
如果您需要做的只是检查频道 capacity/length,您可以像这样使用 reflect
包:
import "reflect"
func CheckChanLen(aChan interface{}) {
rv := reflect.ValueOf(aChan)
if rk := rv.Kind(); rk != reflect.Chan {
panic("expecting type: 'chan ...' instead got: " + rk.String())
}
chanCap := rv.Cap()
chanLen := rv.Len()
fmt.Printf("len:%d cap:%d\n", chanLen, chanCap)
}