我有以下代码定义:
type Tree* = ref ...
type Parser* = ref object
hooks: Table[string, proc(it: var Tree)]
template hook*(this: var Parser, rule: string, body: untyped) =
this.hooks[rule] = proc(it: var Tree) =
body但是,当我试图使用它时,我得到了一个错误" error :未声明的标识符:' it '“,例如:
let gp: Parser = ...
gp.hook("Value"):
echo $it我希望将其翻译为:
gp.hooks["Value"] = proc(it: var Tree) =
echo $it这个很好用。
发布于 2020-06-22 19:27:15
默认情况下,模板中的变量、类型、形式参数和其他参数都是gensym。gensym意味着生成一个有保证的唯一符号,以避免在模板之外的名称冲突。
通过下面的示例,您可以看到它是如何实现的:
template mkproc() =
proc foo(it: var Tree) =
echo it
mkproc()
foo()这将导致以下编译错误:
Error: type mismatch got <> but expected one of:
proc foo(it`gensym123456: var Tree)在那里,it确实是个天才。
要修复hook,就像您的解决方案一样,就是使用{.inject.}标记变量,因为参数不能被标记。
template hook*(this: var Parser, rule: string, body: untyped) =
this.hooks[rule] = proc(it: var Tree) =
var it {.inject.} = it
body最后,像hook这样使用的模板可以从{.dirty.}中受益。这将将所有符号标记为{.inject.},包括proc参数。
template hook*(this: var Parser, rule: string, body: untyped) {.dirty.} =
this.hooks[rule] = proc(it: var Tree) =
body
parser.hook "rule":
echo it发布于 2020-06-18 16:24:55
好的,我找到了解决办法:
template hook*(this: var Parser, rule: string, body: untyped) =
this.hooks[rule] = proc(tree: var Tree) =
var it {.inject.} = tree
body但这是意外的,因为‘它’已经在一个范围内!
https://stackoverflow.com/questions/62453900
复制相似问题