JSRUN 用代码说话

模版

编辑教程

模版

模版是一个简单的替换机制在nim的抽象语法树上操作。模版在编译器的语义分析阶段被处理。它和其他的语言整合的很好,分享没有c语言的预处理宏定义的缺陷。

调用一个模版,就像调用一个程序一样。

Example:

template `!=` (a, b: expr): expr =
  # this definition exists in the System module
  not (a == b)

assert(5 != 6) # the compiler rewrites that to: assert(not (5 == 6))

!=, >, >=, in, notin, isnot 操作都是模版。如果你重载==操作符这是很有益处的,!=操作符可以自动访问和做正确的事情。(除了IEEE浮点数-NaN打破基本的布尔逻辑)

a>b被转换成b<a。a in b被转换成contains(b,a)。notin和isnot有显而易见的含义。

模版对于懒惰评价的目的是非常有用的。 考虑一个简单的logging过程:

const
  debug = true

proc log(msg: string) {.inline.} =
  if debug: stdout.writeln(msg)

var
  x = 4
log("x has the value: " & $x)

这个代码有一个缺点,如果debug被设置为false,$和&操作符依然执行。(对于过程的参数评估is eager)

将log函数转换成模版解决这个问题:

const
  debug = true

template log(msg: string) =
  if debug: stdout.writeln(msg)

var
  x = 4
log("x has the value: " & $x)

模版的参数类型可以是普通类型或者元类型expr(代表表达式),stmt(代表声明),typedesc(代表类型描述)。如果模版没有显示的返回类型,声明用于过程和方法的一致性。

如果这是一个stmt参数,它应该被放到模版声明的最后面。原因是statements可以通过一个特殊的:语法传递给模版。

template withFile(f: expr, filename: string, mode: FileMode,
                  body: stmt): stmt {.immediate.} =
  let fn = filename
  var f: File
  if open(f, fn, mode):
    try:
      body
    finally:
      close(f)
  else:
    quit("cannot open: " & fn)

withFile(txt, "ttempl3.txt", fmWrite):
  txt.writeln("line 1")
  txt.writeln("line 2")

例子中的两个writeln语句被绑定到body参数。withFile样板包含的样板代码有助于避免常见的错误:忘记关闭文件。注意:let fn=filename语句如何确保文件名只被计算一次。

JSRUN闪电教程系统是国内最先开创的教程维护系统, 所有工程师都可以参与共同维护的闪电教程,让知识的积累变得统一完整、自成体系。 大家可以一起参与进共编,让零散的知识点帮助更多的人。
X
支付宝
9.99
无法付款,请点击这里
金额: 0
备注:
转账时请填写正确的金额和备注信息,到账由人工处理,可能需要较长时间
如有疑问请联系QQ:565830900
正在生成二维码, 此过程可能需要15秒钟