我正在尝试创建一个 proc 返回一个自定义元组,其中包含一个 proc 类型的单个元素,即
type
CustomTuple = tuple
foo: proc(input: int): int
proc createCustomTuple(): CustomTuple =
(foo: proc(input: int): int = 10)
Run Code Online (Sandbox Code Playgroud)
但是,当我编译它时,我收到以下错误(我在 Windows 上使用 Nim 1.2.6 版进行编译)。
错误:类型不匹配:得到 <tuple[foo: proc (input: int): int{.noSideEffect, gcsafe, locks: 0.}]> 但预期为 'CustomTuple = tuple[foo: proc (input: int): int{ 。关闭。}]'
所以编译器认为我返回的是一个普通的元组而不是一个,CustomTuple
但我不知道如何改变它以使其工作。Nim 手册中元组的文档显示自定义元组是按照我的方式构造的,我找不到任何从 proc 返回自定义元组的示例。
如果我更改我的CustomTuple
定义以包含不是 procs 的类型,那么它会成功编译,因此它似乎可以执行我的自定义元组,其中包含导致无法编译的 proc。
谁能解释为什么上面的代码没有编译?
我认为我的原始代码不起作用的原因是 Nim 在将过程添加到元组时无法自动将其转换为闭包。Nim 论坛中对此有一些讨论。
由于 proc 未转换为闭包,编译器无法确定返回的元组是 a,CustomTuple
因为类型不匹配,这解释了错误消息。
因此,当将过程打包在元组中时,您需要显式地将其转换为闭包。这可以通过显式转换过程来完成,如下所示:
type
CustomTuple = tuple
foo: proc(input: int): int
proc createCustomTuple(): CustomTuple =
(foo: (proc(input:int):int)(proc(input: int): int = 10))
Run Code Online (Sandbox Code Playgroud)
或者通过添加{.closure.}
这样的编译指示(我认为这更干净)。
type
CustomTuple = tuple
foo: proc(input: int): int
proc createCustomTuple(): CustomTuple =
(foo: proc(input: int): int {.closure.} = 10)
Run Code Online (Sandbox Code Playgroud)
如果您不想执行其中任何一个操作,您可以根据 Salewski 的答案将过程分配给foo
隐式变量的属性。result
这也解释了为什么 Salewski 最初将 proc 分配给foo
隐式result
变量的属性的解决方案有效;在这种情况下,编译器能够自动将 proc 转换为闭包。