为什么golang“推迟”范围功能,而不是词汇圈地

时间:2018-03-23 19:17:25

标签: go

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

计划A

package main
import "fmt"

func main() {  
    defer fmt.Println(1)
    defer fmt.Println(2)
}

计划B

package main
import "fmt"

func main() {  
    {
        defer fmt.Println(1)
    }
    defer fmt.Println(2)
}

换句话说,“defer”语句似乎忽略了词汇封闭[编辑:感谢@twotwotwo纠正我的术语,我的意思是说“阻止”而不是“词汇封闭”]并严格限定在该功能范围内。我想知道:

  1. 我的理解是否正确?
  2. 有没有办法将它范围扩展到块,以便在退出闭包时触发,而不是函数?
  3. 我可以想象按顺序完成几个工作单元,每个单元都需要在继续之前关闭它自己的资源...最好不要仅仅为了这个目的将它们分成单独的函数。

2 个答案:

答案 0 :(得分:1)

  
      
  1. 我的理解是否正确?
  2.   

  
      
  1. 有没有办法将它范围扩大到块[...]?
  2.   

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

defer Go Spec的更多信息。

答案 1 :(得分:1)

正确?

为什么?

如果你只能有一个行为,功能与阻止,哪一个更容易定义另一个?

  • 假设defer适用于阻止。如果您想要更广泛的范围,那么您就无法做到。有时,Go要求您输入新的块,例如在if语句中,这使得在应用延迟时很难轻松控制。

  • 现在,如果defer的范围是函数,那么您可以轻松添加新函数来缩小范围。您甚至可以使用直接调用的匿名函数。

    func() {
        defer ...
    }()