我在nim中有一个表示为泛型的策略:
proc fooStrategy[T](t: T, ...)
proc barStrategy[T](t: T, ...)
我想按名称为策略创建一个查找表...所以我尝试了:
type
Strategy*[T] = proc[T](t: T, ...)
let strategies* = toTable[string, Strategy[T]]([
("foo", fooStrategy), ("bar", barStrategy)])
这不起作用 - 类型声明失败。如果我顺便说一下,我可以猜到战略表也会有问题。还有另一种方法吗? “T”应该是“一些1D集合类型” - 可以是序列,数组,来自blas的向量等。我可以为表添加具体策略以用于常见集合,但我仍然遇到函数指针的问题,如
type
Strategy* = proc(t: any, ...)
let strategies* = toTable[string, Strategy]([
("foo-seq[int]", fooStrategy[int]), ...])
仍有问题。有什么建议吗?
答案 0 :(得分:4)
您的代码存在多个问题:
首先,initTable
不会获取表格的项目列表。它只需要初始大小。您想要使用toTable
。
其次,您必须在创建表时显式设置泛型参数T的值,因为在运行时,所有通用参数都必须绑定到类型。
第三,proc类型必须完全匹配,包括proc上的pragma。这个很棘手。
这是一个有效的例子:
import tables
type
Strategy*[T] = proc(t: T) {.gcsafe, locks: 0.}
proc fooStrategy[T](t: T) = echo "foo"
proc barStrategy[T](t: T) = echo "bar"
let strategies* = toTable[string, Strategy[int]]([
("foo", fooStrategy[int]), ("bar", barStrategy[int])
])
对于此示例,我创建了一个具有Strategy[int]
值的表(您不能拥有Strategy[T]
值的表,因为这不是具体类型)。我使用fooStrategy
实例化barStrategy
和[int]
以匹配表类型。我在类型定义中添加了{.gcsafe, locks: 0.}
。如果省略,则会出现编译器错误:
test.nim(9, 49) Error: type mismatch: got (Array constructor[0..1, (string, proc (t: int){.gcsafe, locks: 0.})])
but expected one of:
proc (pairs: openarray[(string, Strategy[system.int])]): Table[system.string, Strategy[system.int]]{.gcsafe, locks: 0.}
如您所见,编译器会在第一行告诉您它所看到的内容以及第三行中所期望的内容。它会在proc
中看到{.gcsafe, locks: 0.}
,因为这些编译指示会隐式分配给上面定义的proc
。编译指示会更改类型,因此为了能够将proc
分配给Strategy[T]
,您必须将相同的编译指定定义为Strategy[T]
。