我正在使用去1.6(我需要更新).假设我在一个包中有2个文件,我在两个文件fmt中都使用了这个包.您必须fmt在这两个文件中显式导入,或者编译器抛出和错误,这是否意味着它将fmt二进制文件存储在我的可执行文件中两次?
不,那将是一个非常糟糕的设计(最后阅读例外).顺便说一句,检查这个很容易,创建一个名为的包a,包含2个文件:aa.go和ab.go.两个都导入fmt.生成可执行文件(例如go build,必须在main程序包上调用)并检查其大小.现在移动ab.go使用fmt包的所有代码aa.go,并fmt从中删除导入ab.go.再次生成可执行文件.它们的大小相同.
包的完整路径标识.无论有多少文件(同一个软件包)或多少(不同)软件包引用一个软件包,该软件包只会在最终的可执行二进制文件中包含一次.
另请注意,并非所有内容都包含在可执行二进制文件中的已使用包中.某些未使用/提及的内容可能会被排除在外.有关详细信息,请参阅拆分客户端/服务器代码 ; 以及如何在编译时删除未使用的代码?
但有一个例外,即Go 1.8中引入的插件.插件引用的包将包含在已编译的插件中 - 它们必须是 - ,因为插件无法保证将加载它的可执行二进制文件中可用的包.因此,如果fmt包由包引用main,也通过插件引用,则包的代码fmt将包含在两者中(在可执行二进制文件和已编译的插件中).应该注意的是,即使fmt包的代码将出现两次(一次在可执行文件中,一次在插件中),运行时(在内存中)仍然只有一个包的"实例"(例如它的全局变量)将有一个实例,它只会初始化一次).
"边缘"案例是销售包装.如果一个软件包出售在一个vendor文件夹中,并且一个软件包引用了这个被出售的软件包,那么它被认为与原始软件包不同(被出售),如果原始文件也被另一个软件包引用,则两者都将包含在可执行文件中二进制(但它们不被认为是相同的,出售的完整路径与原始的完整路径不同).