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

时间:2017-11-27 12:19:19

标签: go types channel

有以下代码:

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
}

它抛出以下编译时异常:

cannot use msgs (type <-chan amqp.Delivery) as type chan amqp.Delivery in return argument

有什么问题?

1 个答案:

答案 0 :(得分:3)

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

有一些关于频道指示的基本信息here

铊;博士

任何chan t都可以用作定向频道。这增加了一些类型的安全性,使代码更容易理解/使用其他人:

func Foo() <-chan struct{} {
}

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

非定向信道可以是定向的,但由于显而易见的原因,不允许将其转换回非定向信道。您可以在频道类型上查看the spec以获取更多详细信息,但其实质是这个简单的句子:

  

可选&lt; - 运算符指定通道方向,发送或接收。如果没有给出方向,则通道是双向的。频道可能仅限于发送或仅通过转换或分配接收。

溶液

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

func consumeQueue(ch *amqp.Channel, q_Name string) (<-chan amqp.Delivery) {

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