Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Dependencies 关于如何避免Go中的导入周期,有什么好的建议吗?_Dependencies_Go_Circular Dependency - Fatal编程技术网

Dependencies 关于如何避免Go中的导入周期,有什么好的建议吗?

Dependencies 关于如何避免Go中的导入周期,有什么好的建议吗?,dependencies,go,circular-dependency,Dependencies,Go,Circular Dependency,我正在做一个为期一个月的围棋项目。好消息是围棋真的很高效。但是经过一个月的开发,我已经有了数千行代码和许多包。为了避免导入周期对我来说是一个主要问题,每当我遇到导入周期错误时,我都不知道第一次出现问题的地方 Go编译器也只有一个非常简单的注意事项,即始终不足以快速定位问题,例如:main.Go:7:3:import cycle not allowed。它只会帮助您知道哪个文件可能会导致问题,但没有什么比这更深入的了。由于随着代码的增长,import关系变得越来越复杂,我很想知道如何在Go中更有效

我正在做一个为期一个月的围棋项目。好消息是围棋真的很高效。但是经过一个月的开发,我已经有了数千行代码和许多
包。为了避免导入周期对我来说是一个主要问题,每当我遇到导入周期错误时,我都不知道第一次出现问题的地方

Go编译器也只有一个非常简单的注意事项,即始终不足以快速定位问题,例如:
main.Go:7:3:import cycle not allowed
。它只会帮助您知道哪个文件可能会导致问题,但没有什么比这更深入的了。由于随着代码的增长,
import
关系变得越来越复杂,我很想知道如何在Go中更有效地避免导入周期。非常感谢您的帮助

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

有关go list工具的更多信息。

为了补充JML的答案(这有助于“调试”循环引用问题),您可以使用中断这些循环,并结合依赖项注入。对于一个应用程序,我总是尝试遵循的指导原则-请参阅,以获得一个特定于Go的示例-我发现Go的接口“非声明性实现”(即,您不必显式地说
类型MyStruct struct implements IfceSomething
)使这非常简单

因此,如果您有包
A->B->C->A
,那么您可以在包C中创建
InterfaceA
(一些相关的名称,显然比包相关的行为更相关:),并使其依赖于此接口而不是包A,并且确保包A“实现”此接口

然后,您只需要在某一点上提供a到C的具体实现(这里有很多可能性,我通常在主包中“粘合”代码,它了解所有依赖项)

由于导入关系变得越来越复杂,而代码 随着时间的推移,我渴望知道如何更有效地避免导入周期 去吧

另一个选项是可视化项目中的依赖项。这可以通过CLI工具完成。 您可以通过以下方式安装它:

go get -u github.com/kisielk/godepgraph
然后在另一个CLI工具的帮助下,使用它在应用程序中查找导入周期。 使用此工具,您可以可视化包依赖关系:

godepgraph -s path/to/my/package | dot -Tpng -o godepgraph.png
open ./godepgraph.png
要在我的代码中查找周期,请执行以下操作:

除了使用go list工具之外,还可以从体系结构视图确认您已经知道的依赖关系,您需要确保依赖关系树足够深,以便通过构建子组件来了解周期。如果模块中存在导入周期,则应清除存在的周期。应该有足够的模块化(树深度)来无缝地移动这些依赖项

Model -> Field  (Uses A) -- Needs to import "System"
Model -> System (Defines A) -- But needs to import "Field"
----------Move type A Struct A.go to top of module----------
----------This is what the Model Dir looks like now---------
Model -> A
Model -> Field
Model -> System

现在,依赖项已被分离,孩子们可以自由地使用。这可能无助于可视化依赖关系,或者是一个很好的基于工具的解决方案,但是再一次,如果您充分地解耦逻辑并构建子组件,那么您应该很快地在循环中收敛。否则,如果您使用的是树可视化工具,我会说这是万不得已的办法,是设计不佳/子组件不足的结果。

很好知道,实际上,我甚至不知道go列表。较新版本的go为您提供了有关导入周期来源的更多信息
godepgraph -s path/to/my/package | dot -Tpng -o godepgraph.png
open ./godepgraph.png
Model -> Field  (Uses A) -- Needs to import "System"
Model -> System (Defines A) -- But needs to import "Field"
----------Move type A Struct A.go to top of module----------
----------This is what the Model Dir looks like now---------
Model -> A
Model -> Field
Model -> System