0

在 Nim 模板中:作为这个问题的后续,我想到了通过使用重载,甚至在这种情况下,使用普通包装来解决默认参数不可用的问题。不过,如果没有什么东西再次击中粉丝就太好了,让我分享一下:

请注意,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所谓的重写的东西。除了我们得到:

错误:预期的表达式,但发现“关键字丢弃”

那是怎么回事?

4

1 回答 1

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

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

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

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

1
3
于 2018-04-02T20:39:21.990 回答