Подтвердить что ты не робот

Любые хорошие советы о том, как избежать цикла импорта в Go?

Я работаю над проектом Go в течение месяца. Хорошо, что Go действительно очень эффективен. Но через месяц развития у меня уже есть тысячи строк кода и много packages. Чтобы избежать цикла импорта, для меня большая проблема: когда я получаю ошибку цикла импорта, я понятия не имею, где проблема может быть в первый раз.

В компиляторе Go также есть очень простое уведомление, которое всегда недостаточно для быстрого определения проблемы: main.go:7:3: import cycle not allowed. Это поможет вам узнать, какой файл может вызвать проблему, но не более глубоко. Поскольку отношения import становятся все более сложными, а код растет, я очень хочу знать, как избежать эффективного цикла импорта в Go. Любая помощь очень ценится.

4b9b3361

Ответ 1

go list -f '{{join .Deps "\n"}}' <import-path>

Покажет импортные зависимости для пакета в <import-path> - или в текущем каталоге, если <import-path> оставлено пустым. В качестве альтернативы

go list -f '{{join .DepsErrors "\n"}}' <import-path>

надеюсь, покажет полезную информацию в вашем случае. См. Также вывод

go help list

для получения дополнительной информации о инструменте go go.

Ответ 2

Чтобы дополнить ответ jnml (который помогает "отлаживать" проблемы с циклическими ссылками), вы можете использовать инверсию зависимостей, чтобы разбить эти циклы в сочетании с инъекцией зависимостей. Для приложения я всегда стараюсь следовать рекомендациям Чистота архитектуры - см. здесь для Go- конкретный пример - и я нахожу, что Go "не декларативная реализация" интерфейсов (то есть вы не должны явно говорить type MyStruct struct implements IfceSomething) делает это очень простым.

Итак, если у вас есть пакеты A -> B -> C -> A, вы создаете InterfaceA (какое-то релевантное имя, очевидно, больше связано с поведением, чем связанное с пакетом:) в пакете C и заставляет его зависеть от этого интерфейса, а не от пакета A, и вы убедитесь, что пакет "реализует" этот интерфейс.

Тогда вам просто нужно предоставить конкретную реализацию от A до C в какой-то момент (здесь много возможностей, я обычно делаю этот "клей" в основном пакете, который знает обо всех зависимостях).