包源之间的循环依赖关系

时间:2018-10-16 07:37:04

标签: go compiler-errors compilation package

假设您有一个包含两个源文件mypackmypack/a.go的软件包mypack/b.go。这两个源文件都相互依赖,但是Go编译器没有抱怨。如果您将该软件包分为apack/a.gobpack/b.go两个包,则Go编译器会说import cycle not allowed

我对如何处理软件包依赖项的理解是,编译器将构造一个导入图。将对图形进行分析,并以某种方式(我很想学习执行此操作的算法!)来计算编译顺序。如果图中有一个循环,则无法计算顺序,因此编译器会抱怨。

我不了解的是Go编译器如何解决包源之间的依赖关系,但不能解决包之间的依赖关系。如果这两个资源相互依赖,那么您必须进行一些疯狂的杂技,并以某种方式同时编译它们。

有人可以帮我清理一下吗?

2 个答案:

答案 0 :(得分:3)

  

[...] Go编译器如何解决包源之间的依赖关系,但不能解决包之间的依赖关系。如果这两个资源相互依赖,那么您必须进行一些疯狂的杂技,并以某种方式同时编译它们。

该问题基于关于Go代码的结构和编译方式的错误假设:根据定义,源文件没有 没有 。程序包具有依赖性(所有从其所有源文件导入的文件)。依赖关系是软件包(不是源文件)。要编译包,必须在 编译开始之前提供所有依赖项。

您确实必须停止考虑源文件。源文件对Go代码的编译几乎没有任何意义。软件包的源可能包含一个或多个源文件,这基本上是 only 点,源文件将在其中输入编译Go代码。所有相关的内容仅涉及软件包和软件包:编译软件包,导入软件包等。

(仅出于完整性考虑:构建标记在源代码级别起作用,并且程序包初始化可能取决于源代码的组织,并且通过手动调用gc,您可以做的比通过go工具还要多。)

答案 1 :(得分:1)

一个软件包被编译为一个单元,无论使用多少源文件。这真的不应该那么神秘。

此外,您的断言“如果存在周期则无法计算订单”是完全错误的。计算这样的事情很简单-许多语言都可以做到这一点。不过,从政策上来说,Go禁止这样做,因为它会导致代码之间的紧密耦合以及难以理解的代码,而不是因为不可能。