Любые хорошие советы о том, как избежать цикла импорта в Go?
Я работаю над проектом Go в течение месяца. Хорошо, что Go действительно очень эффективен. Но через месяц развития у меня уже есть тысячи строк кода и много packages
. Чтобы избежать цикла импорта, для меня большая проблема: когда я получаю ошибку цикла импорта, я понятия не имею, где проблема может быть в первый раз.
В компиляторе Go также есть очень простое уведомление, которое всегда недостаточно для быстрого определения проблемы: main.go:7:3: import cycle not allowed
. Это поможет вам узнать, какой файл может вызвать проблему, но не более глубоко. Поскольку отношения import
становятся все более сложными, а код растет, я очень хочу знать, как избежать эффективного цикла импорта в Go. Любая помощь очень ценится.
Ответы
Ответ 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 в какой-то момент (здесь много возможностей, я обычно делаю этот "клей" в основном пакете, который знает обо всех зависимостях).