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

问题描述

我正在尝试创建一个proc,该proc返回一个自定义元组,其中包含一个元素,该元素是proc类型,即。

type
  CustomTuple = tuple
    foo: proc(input: int): int

proc createCustomTuple(): CustomTuple =
  (foo: proc(input: int): int = 10)

但是,当我对此进行编译时,出现以下错误(我正在Windows上使用Nim版本1.2.6进行编译。)

错误:类型不匹配:得到了但应为'CustomTuple = tuple [foo:proc(input:int):int {.closure。}]'

因此,编译器认为我要返回一个常规元组而不是CustomTuple,但是我不知道如何更改它以使其正常工作。 Nim manual中的元组文档显示了按我的方式构造的自定义元组,但找不到任何从proc返回自定义元组的示例。

如果我将CustomTuple的定义更改为包含非proc的类型,则它会成功编译,因此看起来它有一些事情要做我的自定义元组,其中包含一个导致proc不能编译的proc。 >

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

解决方法

我认为我的原始代码无法正常工作的原因是因为Nim在将proc添加到元组时无法将proc自动转换为闭包。 There is some discussion around this in the Nim forums.

由于proc未转换为闭包,因此编译器无法确定返回的元组是CustomTuple,因为类型不匹配,从而说明了错误消息。

因此,在将proc封装在元组中时,您需要将其显式转换为闭包。可以通过如下显式转换proc来完成:

type
  CustomTuple = tuple
    foo: proc(input: int): int

proc createCustomTuple(): CustomTuple =
  (foo: (proc(input:int):int)(proc(input: int): int = 10))

或通过添加{.closure.}这样的杂注(我认为它更干净)。

type
  CustomTuple = tuple
    foo: proc(input: int): int

proc createCustomTuple(): CustomTuple =
  (foo: proc(input: int): int {.closure.} = 10)

如果您不想执行上述任何一项操作,则可以根据Salewski的答案将proc分配给隐式foo变量的result属性。

这也解释了Salewski最初将proc分配给隐式foo变量的result属性的解决方案的原因;在这种情况下,编译器能够将proc自动转换为闭包。

,
type
  CustomObject = object
    foo: proc(input: int): int

proc createCustomObject(): CustomObject =
  #(foo: proc(input: int): int = 10)
  #result.foo = proc(input: int): int = 10
  CustomObject(foo: proc(input: int): int = input * 2)

var x = createCustomObject()
echo x.foo(2)