为什么即使对于模板范围内的代码,也需要进行脏注入?

时间:2018-03-31 10:08:00

标签: templates nim hygiene

请考虑以下事项:

import options

template tpl[T](a: untyped) : Option[T] =
  var b {.inject.}: T = 4
  a
  none(int)

discard
  tpl[int]:
    echo b

这构建并运行并产生输出:

  

4

但是,如果你删除 {.inject.} pragma,你会得到:

  

...模板/通用实例化从这里开始   错误:未声明的标识符:'b'

我认为我们不能将代码块echo b视为模板的“内部”,因为:它仅用于扩展模板,并且:它作为参数传递,不在外部使用

我被迫使用肮脏的东西,现在我已经弄脏了我的全球范围来使这项工作?

2 个答案:

答案 0 :(得分:2)

这种方式很有意义。您希望明确用户指定的代码中可用的内容。

您可以使用block

保持全球范围的卫生
import options

template tpl[T](a: untyped) : Option[T] =
  block:
    var b {.inject.}: T = 4
    a
    none(int)

discard
  tpl[int]:
    echo b

答案 1 :(得分:2)

原因是注入的名称是模板公共接口的一部分。您不希望模板的实现细节在用户代码中泄漏,并可能在那里创建命名冲突,因此默认情况下,模板内创建的所有变量都不会隐藏在用户代码中。

使用这样的inject并不算脏,这是正确的做法。