首页 > 解决方案 > 包源之间的循环依赖

问题描述

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

我对如何处理包依赖项的理解是编译器将构建一个导入图。该图被分析并以某种方式(我很想了解执行此操作的算法!)计算编译顺序。如果图中存在循环,则无法计算顺序,因此编译器会抱怨。

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

有人可以帮我解决这个问题吗?

标签: gocompiler-errorscompilationpackage

解决方案


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

这个问题基于对Go 代码的结构和编译方式的错误假设:源文件根据定义没有 依赖关系。一个包具有依赖项(所有来自其所有源文件的导入)。依赖项是包(不是源文件)。要编译一个包,所有依赖项都必须在编译开始之前可用。

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

(只是为了完整性:构建标签在源代码级别工作,包初始化可以依赖于源代码组织,通过手动调用 gc 你可以做比通过 go 工具更多的事情。)


推荐阅读