为什么golang“延迟”的范围是功能,而不是词法外壳

Mag*_*nus 8 go

我惊讶地发现这两个程序产生了相同的输出:

程序A

package main
import "fmt"

func main() {  
    defer fmt.Println(1)
    defer fmt.Println(2)
}
Run Code Online (Sandbox Code Playgroud)

程序B

package main
import "fmt"

func main() {  
    {
        defer fmt.Println(1)
    }
    defer fmt.Println(2)
}
Run Code Online (Sandbox Code Playgroud)

换句话说,“defer”语句似乎无视词法闭包[编辑:感谢@twotwotwo 纠正我的术语,我的意思是说“块”而不是“词法闭包”] 并且严格限定于函数。我想知道:

  1. 我的理解正确吗?
  2. 有没有办法将它的范围限定到块,以便它在退出闭包时触发,而不是函数?

我可以想象按顺序执行多个工作单元,每个工作单元都需要在继续之前关闭自己的资源……最好不必仅出于此目的将它们分解为单独的功能。

jsa*_*ryd 6

  1. 我的理解正确吗?

是的。

  1. 有没有办法将它的范围限定到块 [...]?

没有办法改变defer工作方式。根据您要解决的问题,拆分函数(example)或定义匿名函数(example)可能会有所帮助。后者仅供参考,最好避免使用,因为它会降低代码的可读性。

关于更多信息defer围棋规格


cor*_*ump 5

正确的?

是的。

为什么?

如果你只能有一种行为,函数与块,哪个更容易定义另一个?

  • 假设defer在块上工作。如果您想遵循更广泛的范围,则不能。有时,Go 需要您输入一个新块,例如在if语句中,这使得在应用 defer 时很难轻松控制。

  • 现在,如果defer由函数限定范围,那么您可以轻松添加一个新函数来缩小范围。您甚至可以拥有一个直接调用的匿名函数。

    func() {
        defer ...
    }()
    
    Run Code Online (Sandbox Code Playgroud)