什么是通用程序的 nim 类型定义?
what is nim type definition for generic procedure?
我有一个在 nim 中表示为泛型的策略:
proc fooStrategy[T](t: T, ...)
proc barStrategy[T](t: T, ...)
我想按名称为策略创建一个查找 table...所以我尝试了:
type
Strategy*[T] = proc[T](t: T, ...)
let strategies* = toTable[string, Strategy[T]]([
("foo", fooStrategy), ("bar", barStrategy)])
这不起作用 -- 类型声明失败。如果我能做到这一点,我可以猜测 table 策略也会有问题。还有另一种方法吗? "T" 应该是 "some 1D collection type" —— 可以是序列、数组、来自 blas 的向量等。我可以将具体策略添加到 table 用于常见集合,但我仍然有问题使用函数指针,as
type
Strategy* = proc(t: any, ...)
let strategies* = toTable[string, Strategy]([
("foo-seq[int]", fooStrategy[int]), ...])
还有问题。有什么建议吗?
您的代码存在多个问题:
首先,initTable
没有为 table 获取项目列表。它只需要一个初始大小。您想改用 toTable
。
其次,在创建table时必须显式设置泛型参数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])
])
对于这个例子,我创建了一个 table 和 Strategy[int]
值(你不能有一个 table 和 Strategy[T]
值,因为这不是具体类型)。我用 [int]
实例化 fooStrategy
和 barStrategy
以匹配 table 类型。我在类型定义中添加了 {.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
s 和 {.gcsafe, locks: 0.}
,因为这些 pragmas 被隐式分配给上面定义的 proc
s。 pragmas 改变了类型,所以为了能够将那些 proc
s 分配给 Strategy[T]
,你必须定义相同的 pragmas 到 Strategy[T]
.
我有一个在 nim 中表示为泛型的策略:
proc fooStrategy[T](t: T, ...)
proc barStrategy[T](t: T, ...)
我想按名称为策略创建一个查找 table...所以我尝试了:
type
Strategy*[T] = proc[T](t: T, ...)
let strategies* = toTable[string, Strategy[T]]([
("foo", fooStrategy), ("bar", barStrategy)])
这不起作用 -- 类型声明失败。如果我能做到这一点,我可以猜测 table 策略也会有问题。还有另一种方法吗? "T" 应该是 "some 1D collection type" —— 可以是序列、数组、来自 blas 的向量等。我可以将具体策略添加到 table 用于常见集合,但我仍然有问题使用函数指针,as
type
Strategy* = proc(t: any, ...)
let strategies* = toTable[string, Strategy]([
("foo-seq[int]", fooStrategy[int]), ...])
还有问题。有什么建议吗?
您的代码存在多个问题:
首先,initTable
没有为 table 获取项目列表。它只需要一个初始大小。您想改用 toTable
。
其次,在创建table时必须显式设置泛型参数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])
])
对于这个例子,我创建了一个 table 和 Strategy[int]
值(你不能有一个 table 和 Strategy[T]
值,因为这不是具体类型)。我用 [int]
实例化 fooStrategy
和 barStrategy
以匹配 table 类型。我在类型定义中添加了 {.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
s 和 {.gcsafe, locks: 0.}
,因为这些 pragmas 被隐式分配给上面定义的 proc
s。 pragmas 改变了类型,所以为了能够将那些 proc
s 分配给 Strategy[T]
,你必须定义相同的 pragmas 到 Strategy[T]
.