创建由多个实体使用并使用标准方法导入的 Go 包时,观察到所有实用程序,包括小的,在编译时会产生大的二进制文件。调查该问题表明,整个包都被编译到每个实用程序中,甚至是未使用的函数。
要进一步深入研究该问题,请考虑以下内容code:
main.go:
package main import "play/subplay" func main() { subplay.A() }
play/subplay.go:
package subplay func A() { fmt.Printf("this is function A()") } func B() { fmt.Printf("secret string") }
尽管功能B() 没有被调用,它的字符串值“秘密字符串”出现在编译后的二进制文件 main.exe 中。这种行为提出了如何在编译时消除 Go 程序中未使用的代码的问题。
答案在于 Go 编译器已经处理了这项任务。在编译过程中,编译器将代码打包到存档文件 (.a) 中,并且仅包含可执行二进制文件中的必要组件。它排除了可识别为无法访问的项目。
需要注意的是,如果导入的包导入其他包,则必须递归应用此过滤过程。例如,导入一个导入其他包的包也会导致这些依赖包也被包含在内。
以下是一些说明性示例:
导入包而不使用任何功能:
package main import _ "play/subplay" func main() { }
在这种情况下,生成的二进制文件约为 1 MB。但是,如果导入的包导入了 net/http:
package subplay import _ "net/http" func A() {}
并且您在代码中仍然没有使用 net/http,则由于 net/http 导入,二进制大小将显着增加到大约 5 MB 39 个其他包。
当你开始使用 net/http 但不在主包中调用 subplay.A() 时,可执行文件大小仍然是相同。
package subplay import "net/http" func A() { http.ListenAndServe("", nil) }
只有当您从主包调用 subplay.A() 时,二进制大小才会进一步增加:
package main import "play/subplay" func main() { subplay.A() }
要点是代码包含在可执行二进制文件中的内容直接受到您从导入的包中调用的函数和模块的影响。
此外,必须记住 Go 是静态的链接语言,意味着可执行二进制文件必须包含运行所需的所有内容。
以上是如何在编译时从 Go 二进制文件中消除未使用的代码?的详细内容。更多信息请关注PHP中文网其他相关文章!