任何关于如何避免在Go中导入循环的好build议?
我正在做一个Go项目一个月。 好的是Go非常高效。 但经过一个月的发展,我已经有了数千行代码和许多packages
。 为了避免导入周期对我来说是一个主要的问题,任何时候我有一个导入周期的错误,我不知道这个问题可能在第一时间。
Go编译器也只有非常简单的通知,总是不够好,不能像以下情况main.go:7:3: import cycle not allowed
定位问题: main.go:7:3: import cycle not allowed
。 它只会帮助你知道哪个文件可能导致问题,但没有更深层次的。 由于在代码增长的同时, import
关系变得越来越复杂,所以我很想知道如何在Go中更有效地避免导入循环。 任何帮助深表感谢。
go list -f '{{join .Deps "\n"}}' <import-path>
如果<import-path>
为空,将在<import-path>
或当前目录中显示包的导入依赖关系。 另外
go list -f '{{join .DepsErrors "\n"}}' <import-path>
希望在你的情况下显示一些有用的信息。 另见输出
go help list
获取有关go list工具的更多信息。
为了补充jnml的答案(这有助于“debugging”循环引用问题),可以使用依赖倒置来打破这些循环,再加上dependency injection。 对于一个应用程序,我总是试图遵循Clean架构的指导原则 – 请参阅Go-specific示例 – 我发现Go的接口的“非声明性实现”(也就是说,您不必明确地说type MyStruct struct implements IfceSomething
)使得这非常简单。
因此,如果你有软件包A -> B -> C -> A
,你可以在软件包C中创buildInterfaceA
(一些相关的名字,很明显,与软件包相关的行为相关),并且依赖于这个接口而不是包A,并确保包A“实现”此接口。
那么你只需要在某个时候提供一个具体的A到C的实现(在这里有许多可能性,我通常在知道所有依赖关系的主包中做这个“粘合”代码)。