我相信我理解在正常使用案例中推迟。比如这个问题Golang defer behavior中列出的那个。然而,当一个不返回的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
}
从
调用此函数go start_consumer()
这可能是我误解渠道是如何运作的,但我永远不会回来,因为它正在等待将价值传递给它。
答案 0 :(得分:6)
上一个问题中引用的Go Blog的Defer, Panic, and Recover帖子很好地解释了延迟语句的工作原理。
defer语句将函数调用推送到列表中。在周围函数返回后执行已保存调用的列表。延迟通常用于简化执行各种清理操作的功能。
在你的情况下,由于goroutine没有返回,所以永远不会运行延迟调用列表。这使得在此上下文中不需要延迟语句。