• 向模板传代码块

    向模板传代码块

    您可以在特殊的 : 语法之后将一个语句块作为最后一个参数传递给模板:

    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.  
    11. withFile(txt, "ttempl3.txt", fmWrite): # 特殊冒号
    12. txt.writeLine("line 1")
    13. txt.writeLine("line 2")

    在这个例子中,两个 writeLine 语句绑定到 actions 参数。

    通常将一块代码传递给模板,接受块的参数需要是“untyped”类型。 因为符号查找会延迟到模板实例化时间:

    1. template t(body: typed) =
    2. block:
    3. body
    4.  
    5. t:
    6. var i = 1
    7. echo i
    8.  
    9. t:
    10. var i = 2 # '尝试重新声明i'失败
    11. echo i

    上面的代码因已经声明了 i 的错误信息失败。 原因是 var i = … 需要在传递给 body 参数之前进行类型检查,而Nim中的类型检查意味着符号查找。 为了使符号查找成功,需要将 i 添加到当前(即外部)范围。 在类型检查之后,这些对符号表的添加不会回滚(无论好坏)。 同样的代码可以用 untyped ,因为传递的主体不需要进行类型检查:

    1. template t(body: untyped) =
    2. block:
    3. body
    4.  
    5. t:
    6. var i = 1
    7. echo i
    8.  
    9. t:
    10. var i = 2 # 编译
    11. echo i