包源之间的循环依赖关系



假设您有一个包含两个源文件的包mypackmypack/a.gomypack/b.go。这两个源文件相互依赖,但 Go 编译器不会抱怨。如果你把这个包分成两个,apack/a.gobpack/b.go,Go 编译器会说import cycle not allowed

我对如何处理包依赖项的理解是编译器将构造导入图。图形被分析并以某种方式(我很想了解这样做的算法!(计算编译顺序。如果图中存在循环,则无法计算顺序,因此编译器会抱怨。

我不明白的是 Go 编译器如何能够解决包源之间的依赖关系,但无法解析包之间的依赖关系。如果这两个来源相互依赖,那么你必须做一些疯狂的杂技,并以某种方式同时编译它们。

有人可以为我澄清这一点吗?

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

这个问题是基于关于 Go 代码如何构建和编译的错误假设:根据定义,源文件没有依赖项。 包具有依赖项(从其所有源文件导入的所有内容(。依赖项是包(不是源文件(。要编译包,所有依赖项必须在编译开始之前可用。

您真的必须停止考虑源文件。源文件(几乎(对 Go 代码的编译方式没有任何意义。一个包的源代码可以由一个或多个源文件组成,这基本上是源文件进入编译 Go 代码的唯一点。所有相关内容都围绕着包和包:编译包,导入包等。

(只是为了完整起见:构建标签在源代码级别工作,包初始化可能取决于源代码组织,通过手动调用 gc,您可以做的不仅仅是通过 go 工具。

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

此外,您断言"如果有周期就无法计算订单"是完全错误的。计算这些东西是微不足道的——许多语言都是这样做的。但是,作为政策问题,Go 禁止这样做,因为它会导致代码和难以理解的代码紧密耦合,而不是因为它是不可能的。

最新更新