传递代码块到模板

通过专门的 : 语法,可以将一个语句块传递给模板的最后一个参数:

  1. template withFile(f, fn, mode, actions: untyped): untyped =
  2. var f: File
  3. if open(f, fn, mode):
  4. try:
  5. actions
  6. finally:
  7. close(f)
  8. else:
  9. quit("cannot open: " & fn)
  10. withFile(txt, "ttempl3.txt", fmWrite): # 专门的冒号
  11. txt.writeLine("line 1")
  12. txt.writeLine("line 2")

在这个例子中,那两行 writeLine 语句被绑定到了模板的 actions 参数。

通常,当传递一个代码块到模板时,接受代码块的参数需要被声明为 untyped 类型。因为这样,符号查找会被推迟到模板实例化期间:

  1. template t(body: typed) =
  2. proc p = echo "hey"
  3. block:
  4. body
  5. t:
  6. p() # 因 p 未声明而失败

以上代码错误信息为 p 未被声明。其原因是 p() 语句在传递到 body 参数前执行类型检查和符号查找。 修改模板参数类型为 untyped 使得传递语句体时不做类型检查,同样的代码便可以通过:

  1. template t(body: untyped) =
  2. proc p = echo "hey"
  3. block:
  4. body
  5. t:
  6. p() # 编译通过