do 符号神奇地修复了一个否则被拒绝的表达式作为参数
do notation magically fixes an otherwise refused expression as argument
在 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
无论如何都应该重写的东西。除了我们得到:
Error: expression expected, but found 'keyword discard'
那是怎么回事?
解释原因有点复杂,但你可以这样写重载:
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 节点,这是此处模板的有效输入。此构造通常用于 C-style if 语句,其中包含一个赋值后跟一个 NULL-test:
if (let f = fopen(...); f != 0):
# do something with `f`
正如预期的那样,运行 上述程序的输出将是:
1
3
在 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
无论如何都应该重写的东西。除了我们得到:
Error: expression expected, but found 'keyword discard'
那是怎么回事?
解释原因有点复杂,但你可以这样写重载:
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 节点,这是此处模板的有效输入。此构造通常用于 C-style if 语句,其中包含一个赋值后跟一个 NULL-test:
if (let f = fopen(...); f != 0):
# do something with `f`
正如预期的那样,运行 上述程序的输出将是:
1
3