不能在变量声明中使用 make(IntChannel)(IntChannel 类型的值)作为消费者值

cannot use make(IntChannel) (value of type IntChannel) as Consumer value in variable declaration

我们有以下场景:

package main

type Consumer chan interface {
    OpenChannel()
    CloseChannel()
}

type IntChannel chan int
type StringChannel chan string

func (c IntChannel) OpenChannel() {

}

func (c IntChannel) CloseChannel() {

}

func (c StringChannel) OpenChannel() {

}

func (c StringChannel) CloseChannel() {

}

func main() {

    var dataChannel Consumer = make(IntChannel)
    for data = range dataChannel {

    }
}

目标是 range dataChannel

var dataChannel Consumer = make(IntChannel) 给出错误:cannot use make(IntChannel) (value of type IntChannel) as Consumer value in variable declaration

我们在运行时根据给定的配置值选择整数通道或字符串通道。

阅读此 answer,但帮助不大。


如何在选择 int 数据或字符串数​​据的通道类型上进行测距?

首先,您将 Consumer 声明为 interface{ /* methods */ }chan,这肯定不是您想要的 — 事实上,错误提示您可以'分配 IntChannel 给它。

然后,在将泛型添加到该语言之前,您没有办法保持类型安全。

最接近您想做的事情的解决方案可能是向界面添加一个额外的方法,returns 您可以 range 完成的东西。

type Consumer interface {
    OpenChannel()
    CloseChannel()
    Range() <-chan interface{}
}

type IntChannel chan int

func (c IntChannel) OpenChannel() {
}

func (c IntChannel) CloseChannel() {
}

func (c IntChannel) Range() <-chan interface{} {
    ret := make(chan interface{})
    go func() {
        defer close(ret)
        for v := range c {
            ret <- v
        }
    }()
    return ret
}

func main() {
    c := make(IntChannel)
    var dataChannel Consumer = c
    go func() {
        c <- 12
        close(c)
    }()
    for data := range dataChannel.Range() {
        fmt.Println(data)
    }
}

Go1 游乐场:https://play.golang.org/p/55BpISRVadE


使用泛型(Go 1.18,2022 年初),您可以只定义具有基础类型 chan:

的参数化类型
package main

import "fmt"

type GenericChan[T] chan T

func main() {
    c := make(GenericChan[int])
    go func() {
        c <- 12
        close(c)
    }()
    for data := range c {
        fmt.Println(data)
    }
}

Go2 游乐场:https://go2goplay.golang.org/p/HQJ36ego97i