我在nim中有一个表示为泛型的策略:
proc fooStrategy[T](t: T, ...)
proc barStrategy[T](t: T, ...)
Run Code Online (Sandbox Code Playgroud)
我想按名称为策略创建一个查找表...所以我试过:
type
Strategy*[T] = proc[T](t: T, ...)
let strategies* = toTable[string, Strategy[T]]([
("foo", fooStrategy), ("bar", barStrategy)])
Run Code Online (Sandbox Code Playgroud)
这不起作用 - 类型声明失败.如果我顺便说一下,我可以猜到战略表也会有问题.还有另一种方法吗?"T"应该是"一些1D集合类型" - 可以是序列,数组,来自blas的向量等.我可以为表添加具体策略以用于常见集合,但我仍然遇到函数指针的问题,如
type
Strategy* = proc(t: any, ...)
let strategies* = toTable[string, Strategy]([
("foo-seq[int]", fooStrategy[int]), ...])
Run Code Online (Sandbox Code Playgroud)
还是有问题.有什么建议?
您的代码存在多个问题:
首先,initTable不取表的项目列表。它只需要一个初始大小。你想toTable改用。
其次,您必须在创建表时为泛型参数 T 显式设置一个值,因为在运行时,所有泛型参数都必须绑定到一个类型。
第三,proc 类型必须完全匹配,包括 proc 上的编译指示。这个很棘手。
这是一个工作示例:
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])
])
Run Code Online (Sandbox Code Playgroud)
在这个例子中,我创建了一个带有Strategy[int]值的表(你不能有一个带有Strategy[T]值的表,因为这不是一个具体的类型)。我实例化了fooStrategy和barStrategywith[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.}
Run Code Online (Sandbox Code Playgroud)
如你所见,编译器在第一行告诉你它看到了什么,在第三行告诉你它期望什么。它看到procs with{.gcsafe, locks: 0.}因为这些编译指示被隐式分配给proc上面定义的s。pragma 更改了类型,因此为了能够将这些procs分配给Strategy[T],您必须将相同的 pragma 定义为Strategy[T]。