Templates 模板的默认参数';s表达式
如果我想制作一个模板,可以接受2个Templates 模板的默认参数';s表达式,templates,nim-lang,default-arguments,Templates,Nim Lang,Default Arguments,如果我想制作一个模板,可以接受2个非类型化的参数,并通过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(Excep
非类型化的
参数,并通过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
错误:应为表达式,但找到“关键字放弃”
默认值不被接受,消息很奇怪,discard
是一个表达式,不是吗
注意解决方法:
template tpl(x: bool, body: untyped, bodyFinally: untyped = proc()): void =
# same rest
然后我们得到:
错误:表达式“proc()”的类型为“type proc(){.closure.}”,并且
必须放弃
我已经准备好接受这一点了,尽管我发现这个丢弃需求毫无用处,是一种迂腐的、讨厌的语言,因为它迫使我们在这里这样的通用代码中进行不舒服的练习
让我们再次编辑:
template tpl(x: bool, body: untyped, bodyFinally: untyped = proc()): void =
if x: body
else: discard bodyFinally
现在的结果是:
错误:内部错误:expr(nkProcTy);未知节点类型
确实,没有办法将代码块描述为默认参数值。有两种可能的解决方法:
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
,因为当用户提供非默认值时,无法将bodyFinally
与nil
进行比较。确实无法将代码块描述为默认参数值。有两种可能的解决方法:
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
,因为当用户提供非默认值时,无法将bodyFinally
与nil
进行比较。当bodyFinally为nil
或编译(bodyFinally==nil)
时是否可以使用,因此它不能与is
运算符一起使用。您可能会发现这是违反直觉的,但是对于编译器来说,compiles
要比astToStr
昂贵得多(因为它涉及执行编译器的整个语义过程,而astToStr
是对AST树的简单遍历。非常有趣。python的is
可以执行“is Null”或“is notnull”这就是为什么我需要调整我的思维,使之适应Nim中的是什么意思。同样感谢astToStr
技巧,这是一个很好的建议。答案接受当bodyFinally为nil时,不能使用吗
?nil
不是一种类型,因此它不能与is
运算符一起使用。您可能会发现这与直觉相反,但是编译
对于编译器来说要比astToStr
昂贵得多(因为它涉及执行编译器的整个语义过程,而astToStr
是对AST树的简单遍历。非常有趣。python的is
可以执行“is Null”或“is not Null”这就是为什么我需要调整我的思维,使之适应Nim中的是什么意思。还要感谢astToStr
技巧,这是黄金建议。答案已被接受