接受任何频道的 go 函数

Posted

技术标签:

【中文标题】接受任何频道的 go 函数【英文标题】:go function that accepts any channel 【发布时间】:2021-12-05 13:27:48 【问题描述】:

我想在 go 中编写一个将通用通道作为输入的函数。我希望它能够接受任何频道,无论该频道的类型如何。我以为我可以func myFunc(channel chan interface),但是当我尝试将我的频道传递给它时出现编译错误。有没有办法在 go 中做到这一点?

---编辑---

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

package main

func SendToChannel(arg interface, channel chan interface) error 
    channel<-arg
    //more logic here, potentially returning errors if something goes wrong
    return nil  



func main() 
    IntChan := make(chan int)
    StringChan := make(chan string)
    SendToChannel(1,IntChan)
    SendToChannel("hello",StringChan)
 

但是,这会产生编译错误,因为正如 Kelsnare 指出的那样,chan intchan stringchan interface 是三种完全不同的类型。

在 2022 年仿制药问世之前,这似乎是不可能实现的,但如果有人发现了解决方法,我很想听听。

【问题讨论】:

现在,使用 Go 1.17 及以下版本,您必须这样做:myFunc(channel interface)。明年,使用 Go 1.18 你应该可以做到:myFunc(channel chan T)。如果您有兴趣,可以阅读提案的Channels 部分。 相关:***.com/a/68996854/965900 请提供您遇到的编译错误的详细信息和一些相关代码,创建a Minimal, Reproducible Example供参考。 【参考方案1】:

chan interfacechan int 是两个不同的类型定义。

考虑这个例子:

package main

import (
    "fmt"
)

func myFunc(ch chan interface) 
    fmt.Println("I'm called")


func main() 
    ch := make(chan int)
    myFunc(ch)
    fmt.Println("Done")

这个函数会发生混乱

cannot use ch (type chan int) as type chan interface  in argument to myFunc

我们把类型改成chan interface

package main

import (
    "fmt"
)

func myFunc(ch chan interface) 
    fmt.Println("I'm called")


func main() 
    ch := make(chan interface)
    myFunc(ch)
    fmt.Println("Done")

这会编译。

chan int 用作示例 - 除了 chan interface 作为 ch 的类型之外的任何其他内容都会导致恐慌。

如果您绝对想要一个函数,并且希望能够使用 chan intchan stringchan customtype 中的任何一个来调用,那么您现在唯一的选择就是接受一个普通的 interface

正如@mkopriva 所提到的,泛型即将推出。

【讨论】:

以上是关于接受任何频道的 go 函数的主要内容,如果未能解决你的问题,请参考以下文章

Go结构体方法

Go错误处理

Go语言圣经-Panic异常,Recover捕获异常习题

Go36-19,20-错误处理

Go语言第七篇:Go函数

理解 Go 语言中的方法和接收者