Nim lang Nim:来自过程的返回表

Nim lang Nim:来自过程的返回表,nim-lang,Nim Lang,我一直在尝试在Nim中编写一个简单的lexer,我需要修改我的过程以返回一个表。我在实现这一点时遇到了一些问题,以下是我的代码: 梅因·尼姆 # Code import lexer echo lexer.lex("hi") 莱克瑟·尼姆 import tables proc lex*(code: string): Table = let variable = to_table({"1": "hi"}) return variable 每次尝试编译代码(nimc-r-

我一直在尝试在Nim中编写一个简单的lexer,我需要修改我的过程以返回一个
。我在实现这一点时遇到了一些问题,以下是我的代码:

梅因·尼姆

# Code

import lexer

echo lexer.lex("hi")
莱克瑟·尼姆

import tables

proc lex*(code: string): Table = 
    let variable = to_table({"1": "hi"})

    return variable
每次尝试编译代码(
nimc-r--outDir:“../bin”“main.nim”
)时,我都会遇到以下错误:

/path/to/main.nim(5, 15) template/generic instantiation of `lex` from here
/path/to/lexer.nim(3, 26) Error: cannot instantiate 'Table[A, B]' inside of type definition: 'lex'; Maybe generic arguments are missing?

我可能犯了一些简单的错误,但我在这方面浪费了太多的时间,所以任何帮助都是非常感谢的

操作系统:Solus


Nim版本:1.2.0

代码有几个问题,但让我们开始尝试破译编译器错误:类型定义内的表[A,B]:'lex';可能缺少泛型参数

Nim有类型推断,但假设它是前向声明的,并且在未知的第一时刻失败。在本例中,编译器正在检查
main.nim
文件,并发现您希望使用以下签名调用proc:

proc lex*(code: string): Table
这就是它看到的all,由于
Table
是,它无法实例化返回类型,因为它不知道仅基于proc签名的泛型类型
A
B
应该是什么。这就是编译器所抱怨的。您可能会争辩说,编译器可以尝试查看进程并找出泛型签名的具体类型,但这需要编译器做更多的工作,并且会降低编译时间,这是Nim社区非常关心的一个指标

有两种方法可以解决这个问题,简单的方法是在proc签名中声明类型,困难的方法是在调用者处指定类型。前者是将proc签名更改为以下内容:

proc lex*(code: string): Table[string, string]
echo lexer.lex[Table[string, string]]("hi")
后者是在调用者处指定类型,这意味着将
main.nim
代码更改为:

proc lex*(code: string): Table[string, string]
echo lexer.lex[Table[string, string]]("hi")

不幸的是,第二个解决方案也无法编译,因为
main.nim
模块现在对
Table
type:Error:undeclared identifier:'Table'没有任何内容。为了继续使用此解决方案,您需要从添加的
lexer.nim
中导出
类型,或者在
main.nim
中导入
模块(以及任何其他将来调用的模块)。

代码存在一些问题,但让我们开始尝试破译编译器错误:Table[A,B]'在类型定义中:“lex”;可能缺少泛型参数

Nim具有类型推断,但假设它是前向声明的,并且在第一个未知的时刻失败。在这种情况下,编译器正在检查
main.Nim
文件,并发现您希望调用具有以下签名的进程:

proc lex*(code: string): Table
这就是它所看到的所有的,由于
是,它无法实例化返回类型,因为它不知道基于进程签名的泛型类型
A
B
应该是什么。这就是编译器所抱怨的。你可能会争辩说,编译器可以尝试查看进程并找出泛型签名的具体类型,但这需要编译器做更多的工作,并且会降低编译时间,这是Nim社区非常关心的一个指标

有两种方法可以解决这一问题,简单的方法是在proc签名中声明类型,困难的方法是在调用者处指定类型。前者是将proc签名更改为以下内容:

proc lex*(code: string): Table[string, string]
echo lexer.lex[Table[string, string]]("hi")
后者是在调用者处指定类型,这意味着将
main.nim
代码更改为:

proc lex*(code: string): Table[string, string]
echo lexer.lex[Table[string, string]]("hi")

不幸的是,第二个解决方案也无法编译,因为
main.nim
模块现在对
Table
type:Error:undeclared identifier:“Table”没有任何内容。为了继续使用此解决方案,您需要从
lexer.nim
添加导出
Table
类型,或者导入de>tables
main.nim中的module
(以及任何其他未来调用的模块)。

您需要在proc返回的类型中显式显示。正如Grzegorz所说,更改为:

proc lex*(code: string): Table[string, string] =
足够了。无需修改
main.nim
code中的任何内容

需要考虑的两件小事:

  • Nim procs已经初始化了一个返回类型为隐式返回的
    result
    变量,因此您的
    proc
    可以重写为:

    proc lex*(code: string): Table[string, string] =
      result["1"] = "hi"
    
  • 不需要在main中命名
    lex
    proc,除非存在名称冲突:

    import lexer
    
    lex("hi")
    

  • 您需要在proc返回的类型中显式显示。正如Grzegorz所说,更改为:

    proc lex*(code: string): Table[string, string] =
    
    足够了。无需修改
    main.nim
    code中的任何内容

    需要考虑的两件小事:

  • Nim procs已经初始化了一个返回类型为隐式返回的
    result
    变量,因此您的
    proc
    可以重写为:

    proc lex*(code: string): Table[string, string] =
      result["1"] = "hi"
    
  • 不需要在main中命名
    lex
    proc,除非存在名称冲突:

    import lexer
    
    lex("hi")