模板表达式的默认参数
default arguments to template's expressions
如果我想制作一个可以接受 2 个 untyped
参数的模板,并通过 do
符号传递它们,当我省略第二个 do
我想要一种以参数默认值的形式指定回退的方法。因此:
template tpl(x: bool, body: untyped, bodyFinally: untyped): void =
if x: body
else: bodyFinally
#call site:
var r: int
tpl(true) do:
r = 2
do:
raise newException(Exception, "")
这有效,但是:
template tpl(x: bool, body: untyped, bodyFinally: untyped = discard): void =
# same rest
Error: expression expected, but found 'keyword discard'
不接受默认值,消息很奇怪,discard
是一个表达式不是吗。
尝试解决方法:
template tpl(x: bool, body: untyped, bodyFinally: untyped = proc()): void =
# same rest
然后我们得到:
Error: expression 'proc ()' is of type 'type proc (){.closure.}' and
has to be discarded
虽然我发现这个 discard
要求毫无用处,而且是一种令人讨厌的语言,但我已经准备好接受这一点,因为它迫使我们在像这里这样的通用代码中进行不舒服的体操。
让我们再次编辑:
template tpl(x: bool, body: untyped, bodyFinally: untyped = proc()): void =
if x: body
else: discard bodyFinally
现在结果是:
Error: internal error: expr(nkProcTy); unknown node kind
确实没有办法将代码块描述为默认参数值。有两种可能的work-arounds:
1) 可以通过重载来模拟默认值:
template tpl(x: bool, body: untyped, bodyFinally: untyped) =
if x: body
else: bodyFinally
template tpl(x: bool, body: untyped): void =
tpl(x) do:
body
do:
discard
第二个重载的另一个较短版本是这样的:
template tpl(x: bool, body: untyped): void =
tpl(x, body, (discard))
2) 您可以使用可以在模板中检测到的默认值,例如 nil
:
import macros
template tpl(x: bool, body: untyped, bodyFinally: untyped = nil) =
if x:
body
else:
when astToStr(bodyFinally) == "nil":
discard
else:
bodyFinally
请注意,我必须使用 astToStr
,因为当用户提供 non-default 值时,无法将 bodyFinally
与 nil
进行比较。
如果我想制作一个可以接受 2 个 untyped
参数的模板,并通过 do
符号传递它们,当我省略第二个 do
我想要一种以参数默认值的形式指定回退的方法。因此:
template tpl(x: bool, body: untyped, bodyFinally: untyped): void =
if x: body
else: bodyFinally
#call site:
var r: int
tpl(true) do:
r = 2
do:
raise newException(Exception, "")
这有效,但是:
template tpl(x: bool, body: untyped, bodyFinally: untyped = discard): void =
# same rest
Error: expression expected, but found 'keyword discard'
不接受默认值,消息很奇怪,discard
是一个表达式不是吗。
尝试解决方法:
template tpl(x: bool, body: untyped, bodyFinally: untyped = proc()): void =
# same rest
然后我们得到:
Error: expression 'proc ()' is of type 'type proc (){.closure.}' and has to be discarded
虽然我发现这个 discard
要求毫无用处,而且是一种令人讨厌的语言,但我已经准备好接受这一点,因为它迫使我们在像这里这样的通用代码中进行不舒服的体操。
让我们再次编辑:
template tpl(x: bool, body: untyped, bodyFinally: untyped = proc()): void =
if x: body
else: discard bodyFinally
现在结果是:
Error: internal error: expr(nkProcTy); unknown node kind
确实没有办法将代码块描述为默认参数值。有两种可能的work-arounds:
1) 可以通过重载来模拟默认值:
template tpl(x: bool, body: untyped, bodyFinally: untyped) =
if x: body
else: bodyFinally
template tpl(x: bool, body: untyped): void =
tpl(x) do:
body
do:
discard
第二个重载的另一个较短版本是这样的:
template tpl(x: bool, body: untyped): void =
tpl(x, body, (discard))
2) 您可以使用可以在模板中检测到的默认值,例如 nil
:
import macros
template tpl(x: bool, body: untyped, bodyFinally: untyped = nil) =
if x:
body
else:
when astToStr(bodyFinally) == "nil":
discard
else:
bodyFinally
请注意,我必须使用 astToStr
,因为当用户提供 non-default 值时,无法将 bodyFinally
与 nil
进行比较。