如何将双向通道传递给接受单向通道的函数?

huangapple go评论69阅读模式
英文:

go: how to pass directional channels to a function accepting bidirectional channel?

问题

你好,我可以帮你翻译。以下是翻译好的内容:

你好,我有一个接受 chan []byte 参数的函数(由于没有指定方向,我理解为双向)。这个函数不发送或接收任何内容,只是查看通道中元素的数量,用于统计目的。

我想在以下函数签名的函数内调用这个函数:

func foo(fooChannel chan<- []byte)

但是当我尝试使用参数调用另一个函数时,出现了错误 cannot use fooChannel (type <-chan []byte) as type chan []byte in function argument

有没有办法将 fooChannel 转换为 chan []byte

由于我只对获取一些统计数据感兴趣,我应该如何定义函数原型来接受任何类型的通道(这样我甚至可以摆脱 "byte" 部分)?我只使用 lencap 来处理作为参数接收的通道。

英文:

Hi have a function accepting chan []byte (that, since no direction is specified I understand it is bidirectional). The function does not send or receives anything, only looks at number of elements in the channel for stats related purposes.

I want to call this function within a function with following signature:

func foo(fooChannel chan<- []byte)

But when I try to use argument to call the other function I got the error cannot use fooChannel (type <-chan []byte) as type chan []byte in function argument.

Is there any way to cast fooChannel to chan []byte?

Since I am only interested in getting some stats, how should I prototype the function to accept any type of channel (so I can get rid even of the "byte" part)? I am only using len and cap with channels received as arguments.

答案1

得分: 1

稍作改述:

“有没有一种方法可以将有向通道转换为无向通道?”没有。

“Go语言中是否有‘任意通道’的概念(没有元素类型)?”没有。Go语言没有泛型。

您需要编写多个函数。

英文:

Rephrased a bit:

"Is there a way to cast a directed channel to an undirected?" No there isn't.

"Is there a notion of 'arbitrary channel' (without element type) in Go?" No there isn't. Go has no generics.

You'll have to write several functions.

答案2

得分: 1

有没有办法将fooChannel转换为chan []byte?

不好意思,没有办法将fooChannel转换为chan []byte。这可能只是为了防止有人认为他们仍然可以在接收通道上发送。但是,只是一个小小的问题,不行。

该函数不发送或接收任何内容,只是查看通道中的元素数量以进行统计目的。[...] 我只是使用作为参数接收的通道的lencap

如果它不以任何通道方式使用通道,您可以直接将len(ch)cap(ch)作为参数传递。如果您因为任何原因不喜欢它,您可以使用reflect包进行尝试,它允许您在支持它的任何类型(数组、通道、切片)上调用lencap

这可能是一个不错的开始:

package main

import (
	"fmt"
	"reflect"
)

func stats(i interface{}) {
	v := reflect.ValueOf(i)
	fmt.Printf("%s size: %d/%d\n", v.Kind(), v.Len(), v.Cap())
}

func main() {
	ch := make(chan int, 10)
	ch <- 1
	stats(ch)
}

输出:chan size: 1/10

http://play.golang.org/p/2ehYvEmDkS

英文:

> Is there any way to cast fooChannel to chan []byte?

No, sorry. This is probably just in case someone thinks they would like to send on the receiving channel anyway. But, just a little tiny thing, but... No.

> The function does not send or receives anything, only looks at number of elements in the channel for stats related purposes. [...] I am only using len and cap with channels received as arguments.

If it doesn't use the channel in any channel-ish way, you could simply pass len(ch) and cap(ch) directly as the arguments. If you don't like it for any reason, you can play with reflect package, which will allow you to call len and cap on any type supporting it (array, channel, slice).

This might be a good start:

package main

import (
	&quot;fmt&quot;
	&quot;reflect&quot;
)

func stats(i interface{}) {
	v := reflect.ValueOf(i)
	fmt.Printf(&quot;%s size: %d/%d\n&quot;, v.Kind(), v.Len(), v.Cap())
}

func main() {
	ch := make(chan int, 10)
	ch &lt;- 1
	stats(ch)
}

// Output: chan size: 1/10

http://play.golang.org/p/2ehYvEmDkS

huangapple
  • 本文由 发表于 2015年2月16日 20:41:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/28541658.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定