什么是通用程序的 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] 实例化 fooStrategybarStrategy 以匹配 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.}

如您所见,编译器在第一行告诉您它看到了什么,在第三行告诉您它期望什么。它看到 procs 和 {.gcsafe, locks: 0.},因为这些 pragmas 被隐式分配给上面定义的 procs。 pragmas 改变了类型,所以为了能够将那些 procs 分配给 Strategy[T],你必须定义相同的 pragmas 到 Strategy[T].