Nim 返回包含 proc 的自定义元组

Ben*_*ale 5 tuples nim-lang

我正在尝试创建一个 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。

谁能解释为什么上面的代码没有编译?

Ben*_*ale 4

我认为我的原始代码不起作用的原因是 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 转换为闭包。