Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Templates 模板的默认参数';s表达式_Templates_Nim Lang_Default Arguments - Fatal编程技术网

Templates 模板的默认参数';s表达式

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

如果我想制作一个模板,可以接受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(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
技巧,这是黄金建议。答案已被接受