Nim: вернуть таблицу из процедуры - PullRequest
0 голосов
/ 12 апреля 2020

Я пытался написать простой лексер в Nim, и мне нужно, чтобы моя процедура возвратила Table. У меня были некоторые проблемы с этим, вот мой код:

main.nim

# Code

import lexer

echo lexer.lex("hi")

lexer.nim

import tables

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

    return variable

Каждый раз, когда я попробуйте скомпилировать код (nim c -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

Ответы [ 2 ]

2 голосов
/ 12 апреля 2020

Есть несколько проблем с кодом, но давайте попробуем расшифровать ошибку компилятора: Таблица [A, B] 'внутри определения типа:' lex '; Может быть, отсутствуют общие аргументы c? .

Nim имеет вывод типа, но допустим, что он объявлен вперед и в первый момент завершается неудачно, что-то неизвестно. В этом случае компилятор просматривает ваш файл main.nim и видит, что вы хотите вызвать профи c со следующей подписью:

proc lex*(code: string): Table

Это все , которые он видит и поскольку Table является универсальным c типом , он не может создать экземпляр возвращаемого типа, поскольку не знает, какими должны быть универсальные c типы A или B , основываясь только на профессиональной подписи c. Вот на что жалуется компилятор. Можно утверждать, что компилятор может попытаться заглянуть в pro c и выяснить специфицированный тип c сигнатуры generi c, но это потребует больше работы над частью компилятора и замедлит время компиляции, metri c сообщество Nim заботится о многом.

Есть два способа исправить это: простой, который объявляет типы в подписи pro c, и сложный, который требует Вы должны указать типы у вызывающей стороны. Первый вопрос заключается в том, чтобы изменить подпись pro c на следующую:

proc lex*(code: string): Table[string, string]

Второй - указать тип у вызывающей стороны, что означает изменение кода main.nim на следующий:

echo lexer.lex[Table[string, string]]("hi")

К сожалению, это второе решение также не скомпилируется, поскольку модуль main.nim теперь не имеет ничего общего с типом Table: Ошибка: необъявленный идентификатор: 'Table' . Чтобы продолжать использовать это решение, вам необходимо либо экспортировать тип Table из lexer.nim, добавив оператор экспорта в этот модуль , либо импортировать модуль tables в main.nim (и любые другие другие будущие вызывающие модули).

1 голос
/ 13 апреля 2020

Вы должны быть явно указаны в типе, возвращаемом профессионалом c. Как говорит Гжегож, достаточно изменить на:

proc lex*(code: string): Table[string, string] =

. Нет необходимости что-либо изменять в коде main.nim.

Две незначительные вещи, которые следует учитывать:

  1. Nim Procs уже инициирует переменную result с возвратом type, который неявно возвращается, поэтому ваш proc может быть переписан как:

    proc lex*(code: string): Table[string, string] =
      result["1"] = "hi"
    
  2. Нет необходимости указывать пространство имен lex pro c в main, если только нет имени столкновения:

    import lexer
    
    lex("hi")
    
...