【问题标题】:Nim return custom tuple containing procNim 返回包含 proc 的自定义元组
【发布时间】:2020-12-17 16:48:10
【问题描述】:

我正在尝试创建一个 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 定义更改为包含非 procs 的类型,那么它会成功编译,因此它似乎需要对包含导致无法编译的 proc 的自定义元组进行处理。

谁能解释一下为什么上面的代码不能编译?

【问题讨论】:

    标签: tuples nim-lang


    【解决方案1】:

    我认为我的原始代码不起作用的原因是 Nim 在将 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.} pragma(我认为它更简洁)。

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

    如果您不想执行其中任何一个操作,可以根据 Salewski 的回答将 proc 分配给隐式 result 变量的 foo 属性。

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

    【讨论】:

      【解决方案2】:
      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)
      

      【讨论】:

      • +1 这提供了一个功能等效的解决方案,但实际上并没有解释为什么我的原始代码无法编译这是我真正感兴趣的理解。
      • 请注意,这个解决方案也不需要我们说result.foo = ...,它只是强调使用自定义元组时会发生一些不同的事情。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多