接受任何通道的Go函数

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

go function that accepts any channel

问题

我想在Go语言中编写一个函数,该函数以通用通道作为输入。我希望它能够接受任何类型的通道作为输入。我尝试使用func myFunc(channel chan interface{}),但是当我尝试将我的通道传递给它时,出现了编译错误。在Go语言中有没有办法实现这个功能?

---编辑---

有人要求我提供一个最小工作示例,所以我想在下面分享一些代码。我希望的是类似以下的代码:

  1. package main
  2. func SendToChannel(arg interface{}, channel chan interface{}) error {
  3. channel<-arg
  4. //更多逻辑在这里,如果出现问题可能返回错误
  5. return nil
  6. }
  7. func main() {
  8. IntChan := make(chan int)
  9. StringChan := make(chan string)
  10. SendToChannel(1,IntChan)
  11. SendToChannel("hello",StringChan)
  12. }

然而,这会导致编译错误,因为正如Kelsnare指出的那样,chan intchan stringchan interface{}是完全不同的类型。

看起来在2022年之前可能无法实现这个功能,除非泛型功能推出,但如果有人发现了解决方法,我很愿意听听。

英文:

I would like to write a function in go that takes a generic channel as an input. I'd like it to be able to accept any channel regardless of what type that channel is for. I assumed I could us func myFunc(channel chan interface{}) but I'm getting a compilation error when I try to pass my channel to it. Is there a way to do this in go?

---EDIT---

I've been asked for a minimal working example, so I thought I'd share some code below. What I would like is something along the lines of

  1. package main
  2. func SendToChannel(arg interface{}, channel chan interface{}) error {
  3. channel&lt;-arg
  4. //more logic here, potentially returning errors if something goes wrong
  5. return nil
  6. }
  7. func main() {
  8. IntChan := make(chan int)
  9. StringChan := make(chan string)
  10. SendToChannel(1,IntChan)
  11. SendToChannel(&quot;hello&quot;,StringChan)
  12. }

However, this gives a compilation error because, as Kelsnare pointed out, chan int, chan string and chan interface{} are three completely different types.

It seems likely that this will not be possible to achieve until generics come out in 2022, but if anyone has discovered a workaround I'd love to hear it.

答案1

得分: 3

chan interface{}chan int是两个不同的类型定义。

考虑以下示例:

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func myFunc(ch chan interface{}) {
  6. fmt.Println("I'm called")
  7. }
  8. func main() {
  9. ch := make(chan int)
  10. myFunc(ch)
  11. fmt.Println("Done")
  12. }

这个函数会引发以下错误:

  1. cannot use ch (type chan int) as type chan interface {} in argument to myFunc

让我们将类型更改为chan interface{}

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func myFunc(ch chan interface{}) {
  6. fmt.Println("I'm called")
  7. }
  8. func main() {
  9. ch := make(chan interface{})
  10. myFunc(ch)
  11. fmt.Println("Done")
  12. }

这个版本可以编译通过。

chan int只是一个示例 - 除了将ch的类型设置为chan interface{}之外,任何其他类型都会导致错误。

如果你确实希望编写一个可以接受任何类型的chan intchan stringchan customtype的函数,目前唯一的选择是接受一个普通的interface{}类型参数。

正如@mkopriva提到的,泛型即将到来。

英文:

chan interface{} and chan int are two distinct type definitions.

Consider this example:

  1. package main
  2. import (
  3. &quot;fmt&quot;
  4. )
  5. func myFunc(ch chan interface{}) {
  6. fmt.Println(&quot;I&#39;m called&quot;)
  7. }
  8. func main() {
  9. ch := make(chan int)
  10. myFunc(ch)
  11. fmt.Println(&quot;Done&quot;)
  12. }

This function panics with

  1. cannot use ch (type chan int) as type chan interface {} in argument to myFunc

Let's change the type to chan interface{}

  1. package main
  2. import (
  3. &quot;fmt&quot;
  4. )
  5. func myFunc(ch chan interface{}) {
  6. fmt.Println(&quot;I&#39;m called&quot;)
  7. }
  8. func main() {
  9. ch := make(chan interface{})
  10. myFunc(ch)
  11. fmt.Println(&quot;Done&quot;)
  12. }

This compiles.

chan int is used as an example - anything else apart from chan interface{} as the type for ch will result in a panic.

If you absolutely want a function that you want to be able to call with any of chan int, chan string, chan customtype your only bet right now is to accept a plain interface{}.

As @mkopriva mentioned though, generics are coming soon.

huangapple
  • 本文由 发表于 2021年10月18日 21:26:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/69616953.html
匿名

发表评论

匿名网友

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

确定