Defer 语句

使用 defer 语句代替 try finally 语句可以避免代码的复杂嵌套,从作用域的角度看也更加灵活。下面给了例子。

在 defer 之后的任意语句,都认为处在当前块的隐式 try 块中:

  1. proc main =
  2. var f = open("numbers.txt", fmWrite)
  3. defer: close(f)
  4. f.write "abc"
  5. f.write "def"

重写为:

  1. proc main =
  2. var f = open("numbers.txt")
  3. try:
  4. f.write "abc"
  5. f.write "def"
  6. finally:
  7. close(f)

当 defer 位于模板/宏的最外层作用域时,它的作用域将延伸到调用模板/宏的那个代码块中:

  1. template safeOpenDefer(f, path) =
  2. var f = open(path, fmWrite)
  3. defer: close(f)
  4. template safeOpenFinally(f, path, body) =
  5. var f = open(path, fmWrite)
  6. try: body # 若不使用 `defer` ,`body` 必须指定为参数
  7. finally: close(f)
  8. block:
  9. safeOpenDefer(f, "/tmp/z01.txt")
  10. f.write "abc"
  11. block:
  12. safeOpenFinally(f, "/tmp/z01.txt"):
  13. f.write "abc" # 增加一级词法作用域
  14. block:
  15. var f = open("/tmp/z01.txt", fmWrite)
  16. try:
  17. f.write "abc" # 增加一级词法作用域
  18. finally: close(f)

Nim 不允许在最顶层使用 defer 语句,因为不确定这样的语句涉及哪些内容。