go - 包源之间的循环依赖
问题描述
假设您有一个mypack
包含两个源文件mypack/a.go
和mypack/b.go
. 这两个源文件相互依赖,但 Go 编译器不会抱怨。如果你把那个包分成两个,apack/a.go
and bpack/b.go
,Go 编译器会说import cycle not allowed
.
我对如何处理包依赖项的理解是编译器将构建一个导入图。该图被分析并以某种方式(我很想了解执行此操作的算法!)计算编译顺序。如果图中存在循环,则无法计算顺序,因此编译器会抱怨。
我不明白的是 Go 编译器如何能够解决包源之间的依赖关系,但无法解决包之间的依赖关系。如果这两个来源相互依赖,那么您必须做一些疯狂的杂技并以某种方式同时编译它们。
有人可以帮我解决这个问题吗?
解决方案
[...] Go 编译器如何能够解决包源之间的依赖关系,但不能解决包之间的依赖关系。如果这两个来源相互依赖,那么您必须做一些疯狂的杂技并以某种方式同时编译它们。
这个问题基于对Go 代码的结构和编译方式的错误假设:源文件根据定义没有 依赖关系。一个包具有依赖项(所有来自其所有源文件的导入)。依赖项是包(不是源文件)。要编译一个包,所有依赖项都必须在编译开始之前可用。
你真的必须停止考虑源文件。源文件(几乎)对 Go 代码的编译方式没有任何意义。一个包的源代码可能由一个或多个源文件组成,这基本上是源文件进入编译 Go 代码的唯一点。一切相关的东西都只围绕包和包:编译包、导入包等。
(只是为了完整性:构建标签在源代码级别工作,包初始化可以依赖于源代码组织,通过手动调用 gc 你可以做比通过 go 工具更多的事情。)
推荐阅读
- python - Python:在类主体中动态创建子类
- android - 将 Gradle 升级到版本 4 后生成错误
- angular - 无法解析 DialogService 的所有参数:(?, ?, ?)
- c++ - 如何在最前沿的 linux 上编译程序以在旧 linux 上运行
- sql - 如何对oracle sql中的数字字符串进行数学比较
- bash - 在 tgz 的所有文件中搜索一个文本
- android - Glide.with(context).load("file://"+bitmapList.get(position)) 显示错误?
- javascript - 使用 AJAX/jQuery 将内容加载到 div
- javascript - 如何将数组与 jQuery.val 一起使用
- sql - 与 max 连接的 SQL 表