【问题标题】:How do import statements get resolved in multiple source files?如何在多个源文件中解析导入语句?
【发布时间】:2017-08-19 23:08:20
【问题描述】:

我一直试图找到这个问题的答案,但没有成功。

当一个包由多个源文件组成时,问题是关于 Go 中的 import 语句。

假设我有一个名为 math 的包,其中包含多个文件:

|-- math
   |-- add.go
   |-- subtract.go
   |-- divide.go
   |-- multiply.go

假设math 包使用fmt 包,因此它需要适当的导入语句。但是由于我们有四个单独的文件,我们必须多次导入fmt 包(至少在我的理解中):

// add.go
import "fmt"

// subtract.go
import "fmt"

// divide.go
import "fmt"

// multiply.go
import "fmt"

现在的问题是,编译包时会发生什么?语句是否简单地合并在一起?

如果是这样,为什么我们必须多次导入包(每个文件一次),而不仅仅是一个包含所有导入语句的文件,以免重复自己?

【问题讨论】:

    标签: go packages


    【解决方案1】:

    specification says:

    导入包的包名范围是包含导入声明的文件的文件块。

    由于导入没有包范围,因此导入不会合并在一起,并且在使用导入的每个文件中都是必需的。

    导入的范围与编译器和链接器如何加载导入的包无关。这些工具足够聪明,可以一次加载任何给定的包。

    【讨论】:

    • 那么当我四次导入fmt 包时,编译器如何确保它不会在同一个构建中四次链接包?我假设由于 import 语句只有“文件范围”,编译器必须以某种方式组合所有导入的库以避免将同一个库链接两次。
    • 编译器只构建任何包一次。如果您想知道如何这样做,请阅读编译源代码,它是open source and available on GitHub
    • @Rtsne42 标识符的范围与编译器和链接器如何加载包无关。这些工具足够聪明,可以一次加载任何给定的包。
    • @CeriseLimón 谢谢,我确信他们只加载了一次包。我只是想知道当多个文件中有重复的导入语句时它是如何做到的。也就是说,您的回答确实为我澄清了一些事情。
    猜你喜欢
    • 1970-01-01
    • 2023-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多