向模板传代码块
您可以在特殊的 : 语法之后将一个语句块作为最后一个参数传递给模板:
- template withFile(f, fn, mode, actions: untyped): untyped =
- var f: File
- if open(f, fn, mode):
- try:
- actions
- finally:
- close(f)
- else:
- quit("cannot open: " & fn)
- withFile(txt, "ttempl3.txt", fmWrite): # 特殊冒号
- txt.writeLine("line 1")
- txt.writeLine("line 2")
在这个例子中,两个 writeLine 语句绑定到 actions 参数。
通常将一块代码传递给模板,接受块的参数需要是“untyped”类型。 因为符号查找会延迟到模板实例化时间:
- template t(body: typed) =
- block:
- body
- t:
- var i = 1
- echo i
- t:
- var i = 2 # '尝试重新声明i'失败
- echo i
上面的代码因已经声明了 i 的错误信息失败。 原因是 var i = … 需要在传递给 body 参数之前进行类型检查,而Nim中的类型检查意味着符号查找。 为了使符号查找成功,需要将 i 添加到当前(即外部)范围。 在类型检查之后,这些对符号表的添加不会回滚(无论好坏)。 同样的代码可以用 untyped ,因为传递的主体不需要进行类型检查:
- template t(body: untyped) =
- block:
- body
- t:
- var i = 1
- echo i
- t:
- var i = 2 # 编译
- echo i