不能在返回参数中使用 msgs(类型 <-chan _)作为类型 chan _

Rud*_*koŭ 3 types channel go

有以下代码:

func consumeQueue(ch *amqp.Channel, q_Name string) (chan amqp.Delivery) {
    msgs, err := ch.Consume(
        q_Name, // queue
        "",     // consumer
        true,   // auto-ack
        false,  // exclusive
        false,  // no-local
        false,  // no-wait
        nil,    // args
    )
    failOnError(err, "Failed to register a consumer")   
    return msgs
}
Run Code Online (Sandbox Code Playgroud)

它抛出以下编译时异常:

cannot use msgs (type <-chan amqp.Delivery) as type chan amqp.Delivery in return argument
Run Code Online (Sandbox Code Playgroud)

怎么了?

Eli*_*gem 5

这非常简单。您尝试返回一个定向通道(在本例中为只读通道)作为可用于读取和写入的通用通道。

有一些关于通道方向的基本信息这里

塔尔;博士

Any 都chan t可以用作定向通道。这增加了整体类型安全性,并使代码更容易被其他人理解/使用:

func Foo() <-chan struct{} {
}
Run Code Online (Sandbox Code Playgroud)

这告诉我Foo返回一个我可以读取的频道。如果它只是返回chan struct{},我必须检查文档以查看是否需要将某些内容推送到该通道或从该通道接收。

非定向通道可以变为定向通道,但由于显而易见的原因,不允许转换回非定向通道。您可以查看通道类型的规范以获取更多详细信息,但其本质是这样简单的一句话:

可选的 <- 运算符指定通道方向、发送或接收。如果没有给出方向,则通道是双向的。通过转换或分配,通道可能被限制为仅发送或仅接收。

解决方案

在您的特定情况下,解决方案很简单:更改返回类型以匹配您拥有的通道:

func consumeQueue(ch *amqp.Channel, q_Name string) (<-chan amqp.Delivery) {
Run Code Online (Sandbox Code Playgroud)

正如您所注意到的:当您尝试将定向通道转换为双向通道时,编译器会对您大喊大叫。当您尝试将读取通道转换为写入通道(写为chan<- amqp.Delivery)时,您也会收到类似的错误。因此,如果您从编译器收到类型错误消息,只需检查它提到的类型...Go 的编译器会吐出相当不言自明的错误(IMO)