模板表达式的默认参数 [英] default arguments to template's expressions

查看:125
本文介绍了模板表达式的默认参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我想制作一个可以接受2个无类型参数的模板,并通过 do 标记传递它们,当我省略第二个 do 时,我想有一种方法可以以参数默认值的形式指定回退。像这样:

If I want to make a template that can accept 2 untyped arguments, and pass them through do notation, when I omit the second do I'd like to have a way to specify a fallback in the form of a parameter's default value. as such:

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 是一个表达式是不是

The default value is not accepted, and the message is weird, discard is an expression isn't it.

解决方法的提示:

template tpl(x: bool, body: untyped, bodyFinally: untyped = proc()): void =
  # same rest

然后我们得到:


错误:表达式'proc()'的类型为proc类型(){。closure。}'和
必须被丢弃

Error: expression 'proc ()' is of type 'type proc (){.closure.}' and has to be discarded

我已经准备好接受,即使尽管我发现此丢弃要求毫无用处,但对语言却很讨厌,因为它迫使我们陷入通用代码这样不舒服的体操中。

I'm moderately ready to accept that, even though I find this discard requirement uselessly pedant, and a nuisance of the language, since it's forcing us into uncomfortable gymnastics in generic code like here.

再次编辑:

template tpl(x: bool, body: untyped, bodyFinally: untyped = proc()): void =
  if x: body
  else: discard bodyFinally

现在结果是:


错误:内部错误:expr(nkProcTy);未知节点种类

Error: internal error: expr(nkProcTy); unknown node kind


推荐答案

确实没有办法将代码块描述为默认参数值。有两种可能的解决方法:

It's true that there is no way to describe a block of code as a default parameter value. There are two possible work-arounds for this:

1)您可以通过重载来模拟默认值:

1) You can simulate the default values through an overload:

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

第二个重载的另一个简短版本是:

Another shorter version of the second overload would be this:

template tpl(x: bool, body: untyped): void =
  tpl(x, body, (discard))

2)您可以使用默认值,例如 nil ,可以在模板内检测到该值:

2) You can use a default value like nil that can be detected inside the template:

import macros

template tpl(x: bool, body: untyped, bodyFinally: untyped = nil) =
  if x:
    body
  else:
    when astToStr(bodyFinally) == "nil":
      discard
    else:
      bodyFinally

请e注意我必须使用 astToStr ,因为无法将 bodyFinally 与<$ c $进行比较c> nil 当用户提供非默认值时。

Please note that I had to use astToStr, because it won't be possible to compare bodyFinally to nil when the user supplies a non-default value.

这篇关于模板表达式的默认参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆