德弗尔打电话去常规

msc*_*ett 1 go

我相信我理解在正常使用情况下推迟.比如这个问题中列出的Golang defer行为.然而,当一个不返回的goroutine内部调用defer时,我有点感到困惑.这是有问题的代码.

func start_consumer() {
    conn, _ := amqp.Dial("amqp://username:password@server.com")
    //defer conn.Close()

    ch, _ := conn.Channel()
    //defer ch.Close()

    q, _ := ch.QueueDeclare(
        "test", // name
        true,   // durable
        false,  // delete when unused
        false,  // exclusive
        false,  // no-wait
        nil,    // arguments
    )

    _ = ch.Qos(
        3,     // prefetch count
        0,     // prefetch size
        false, // global
    )

    forever := make(chan bool)

    go func() {
        for {
            msgs, _ := ch.Consume(
                q.Name, // queue
                "",     // consumer
                false,  // ack
                false,  // exclusive
                false,  // no-local
                false,  // no-wait
                nil,    // args
            )

            for d := range msgs {
                log.Printf("Received a message: %s", d.Body)
                d.Ack(true)
            }

            time.Sleep(1 * time.Second)
        }
    }()

    log.Printf(" [*] Waiting for messages. To exit press CTRL+C")
    <-forever
}
Run Code Online (Sandbox Code Playgroud)

从中调用此函数

go start_consumer()
Run Code Online (Sandbox Code Playgroud)

这可能是我误解了渠道是如何运作的,但我永远不会回来,因为它正在等待一个值传递给它.

小智 6

上一个问题中引用的Go Blog的Defer,Panic和Recover帖子可以很好地解释延迟语句的工作原理.

defer语句将函数调用推送到列表中.在周围函数返回后执行已保存调用的列表.延迟通常用于简化执行各种清理操作的功能.

在你的情况下,由于goroutine没有返回,所以永远不会运行延迟调用列表.这使得在此上下文中不需要延迟语句.