#go #go-modules
#Вперед #go-модули
Вопрос:
Я работаю над текстом «Написание интерпретатора в Go» Торстена Болла, чтобы узнать о языке.
Каталог проекта выглядит следующим образом:
Interpreter/
|---code/
| |---token/
| | |---token.go
| | |---go.mod
| |---lexer/
| |---lexer_test.go
| |---go.mod
|---go.mod
Я создал файлы go.mod таким образом
>go mod init monkey
>cd token
>go mod init token
>cd ../lexer
>go mod init lexer
Я добавил эту строку в файл go.mod в модуле lexer
replace monkey/token => ../token
При запуске go test
из папки lexer я получаю ожидаемый результат, как указано в книге, но я понимаю, что это не показатель правильной настройки проекта.
>go test
# lexer [lexer.test]
./lexer_test.go:26:7: undefined: New
FAIL lexer [build failed]
Но при запуске тестов, как указано в книге, т. Е. Из кода корневой папки следующим образом:
go test ./lexer
go не может разрешить пакет lexer, и я получаю следующую ошибку
main module (monkey) does not contain package monkey/lexer
Есть ли что-то, что нужно было добавить в файл go.mod в корневой папке, чтобы исправить это?
Комментарии:
1. У вас должен быть один go.mod для каждого проекта, а не по одному для каждого пакета. Затем, чтобы протестировать все, что вы можете сделать из корня
go test ./...
.2. Хорошо, спасибо за ответ. Я удалил файлы модов в подкаталогах и получил ожидаемый результат. Кроме того,
go mod init monkey
правильный ли способ создания go.mod в корневом каталоге? Нужно ли мне добавить к нему что-нибудь еще?3. В общем случае вы должны указать «путь» к модулю
go mod init
вместо просто имени. «Путь к модулю должен описывать как то, что делает модуль, так и то, где его найти. Обычно путь к модулю состоит из корневого пути репозитория, каталога в репозитории (обычно пустого) и суффикса основной версии (только для основной версии 2 или выше).» Напримерgo mod init github.com/kchak/monkey
. Подробнее читайте здесь: golang.org/ref/mod#module-path . — Обратите внимание, что это не является обязательным требованием, и в конечном итоге это зависит от вас, если вы хотите использовать толькоmonkey
это, должно быть в порядке.4. Обратите внимание, что путь к модулю становится префиксом путей импорта пакетов внутри модуля. Так, например, если
lexer
пакет хочет импортироватьtoken
пакет, он должен указать путь импорта какimport "github.com/kchak/monkey/code/token"
.5. Модуль — это набор пакетов, объединенных вместе.
Ответ №1:
Как отмечает @mkopriva, простым решением является удаление go.mod
файлов из каталогов token
and lexer
.
В общем, проект Go должен иметь один go.mod
файл в корне проекта: каждый go.mod
файл указывает на автономный модуль.
Ответ №2:
Решение было
$ cd 01/src/monkey
$ go mod init monkey
$ go test ./lexer