当前位置: 首页 > 面试题库 >

如何在编译时删除未使用的代码?

徐峰
2023-03-14
问题内容

我们已经构建了一个Go包,供我们许多人使用。

它是使用标准import ("package-name")方法导入的。

但是,在编译时,我们所有的实用程序(包括很小的实用程序)最终都是很大的二进制文件。

我们提取了实用程序中的所有字符串,并发现整个软件包都被编译到每个实用程序中。包括那些实用程序未使用的功能。

编辑1:

谢谢回答这个问题的人。

这是我们所看到的:

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中找到了字符串“ secret string”。

我们如何在编译时从Go程序中删除未使用的代码?


问题答案:

编译器已经做到了。所有代码都以包文件(.a)结尾,但是在可执行二进制文件中,Go工具并不包括导入包中的所有内容,仅包括所需的内容(或更确切地说,它排除了可能无法访问的内容)。

这里要注意的一件事:如果一个导入的包(您只想从中包含您所引用的内容)导入了其他包,那么这当然必须递归地完成。

例如,如果您导入此程序包:

package subplay

func A() {}

并从中调用任何内容:

package main

import _ "play/subplay"

func main() {
}

结果二进制文件(Go 1.8,linux,amd64)将为960,134字节(大约1 MB)。

如果更改subplay为导入net/http

package subplay

import _ "net/http"

func A() {}

但是仍然不要从中调用任何内容net/http,结果将是: 5,370,935字节 (大约5
MB)!(请注意,net/http还要导入其他39个软件包!)

现在,如果您开始使用以下内容net/http

package subplay

import "net/http"

func A() {
    http.ListenAndServe("", nil)
}

但是在main程序包中您仍然不调用subplay.A(),可执行二进制文件的大小 不会改变:仍然为5,370,935字节

当您将main包更改为call时subplay.A()

package main

import "play/subplay"

func main() {
    subplay.A()
}

结果二进制数 增长:5,877,919字节

如果更改http.ListenAndServe()http.ListenAndServeTLS()

func A() {
    http.ListenAndServeTLS("", "", "", nil)
}

结果二进制为: 6,041,535字节

如您所见,编译到可执行二进制文件中的内容 确实取决于您 从导入包中 调用/使用 的内容。

同样不要忘记Go是一种静态链接的语言,结果可执行二进制文件必须包含它需要的所有内容。



 类似资料:
  • 问题内容: 在关于反射的本教程中,它指出: […]因为泛型是通过类型擦除实现的,因此在编译过程中会删除有关泛型类型的所有信息 我的知识是使用泛型,以便在编译时编译器可以检查类型安全性。即失败快速方法。但是该链接提到类型擦除会在编译期间删除通用信息。 问题答案: 您引用的语句是正确的:编译器在编译过程中在内部使用通用类型信息,在处理源时会生成与类型相关的错误。然后,一旦完成验证,编译器将生成类型擦除

  • 问题内容: 我想知道是否有C的Java等效项 可以在我们不想编译的代码块周围使用。添加块引号: 也有相同的效果,但是问题是,我们必须确保没有单行注释 在块中。 问题答案: Java中没有预处理程序指令。最好的选择是注释掉代码。

  • 编译/安装程序 https://github.com/vivo-project/VIVO 使用maven我运行: mvn install-e-s安装程序/settings.xml 我对代码做了一些小的更改,但我注意到我的更改在这个cmd运行时被删除了。有没有办法阻止我的更改被删除?

  • 我使用Java-8编译器编译了以下代码:

  • 问题内容: 我习惯于自动重新格式化我的代码,使其整洁并保持导入顺序。但是有时,它与IDE自动保存一起以不舒服的方式工作。像这种情况: 我想将新包添加到我的代码中。 然后,我将其安装并刷新我的IDE缓存。 我可以轻松地使用带有IDE自动完成和导航功能的软件包。 和IDE 会发生什么? 我添加新包裹 为了运行,我必须保存一个文件 查找未使用的软件包并将其从导入中删除。不好。 解决方法: A.手动添加新

  • 我正在尝试学习java的这个新GWT部分。。。 我做了我的第一个简单的应用程序 我命名了 我的模块:-HelloWorld 我收到以下错误: 2014年4月18日下午4:00:53爪哇。util。首选项。WindowsPreferences警告:无法在根0x8000002处打开/创建prefs根节点Software\JavaSoft\prefs。Windows RegCreateKeyEx(…)返