用符号神奇地修复一个否则被拒绝的表达式作为参数

时间:2018-04-02 15:44:02

标签: templates nim do-notation

在Nim模板中:作为this problem的后续内容,我想通过使用重载或甚至在这种情况下使用普通包装来解决默认参数不可用性。但是,如果某些东西没有再次击中粉丝那就太好了,让我分享一下:

请注意,bodyFinally现在是一个很难(必须指定)的参数。

template tpl(x: bool, body: untyped, bodyFinally: untyped): void =
  if x: body
  else: bodyFinally

# we add a convenience helper with 2 args here.
template tpl2(x: bool, body: untyped): void =
  tpl(x) do:
    body
  do:
    discard

#call site:
var r: int
tpl2(true) do:
  r = 2
很酷(很有效)。虽然这不是我tpl2的第一枪;这是:

template tpl2(x: bool, body: untyped): void =
  tpl(x, body, discard)

因为do所谓的重写事情。除了我们得到:

  

错误:预期表达式,但找到'关键字丢弃'

那又是什么呢?

1 个答案:

答案 0 :(得分:3)

解释原因有点复杂,但你可以像这样编写过载:

template tpl(x: bool, body: untyped, bodyFinally: untyped) =
  if x: body
  else: bodyFinally

template tpl(x: bool, body: untyped): void =
  tpl(x, body, (discard))

var r = 1

tpl(false):
  r = 2

echo r

tpl(true):
  r = 3

echo r

额外的括号触发一个特殊的解析规则,生成nkStmtListExpr AST节点,这是模板的有效输入。此构造通常用于包含赋值后跟NULL测试的C样式if语句:

if (let f = fopen(...); f != 0):
  # do something with `f`

正如预期的那样,运行上述程序的输出将是:

1
3