我喜欢将模块/软件包分成许多文件(例如,较大的功能文件和耦合的帮助程序文件)。现在,模块可以随着扩展而具有许多更大的功能。假设我的模块/软件包每个都包含大约30个文件。
几天前我开始使用Go时,我对模块模式有些困惑。我有JavaScript(ES6 +)背景。经过研究,我发现您可以通过运行以下命令go build ./...
来构建由多个文件组成的软件包。效果很好,直到我的程序包包含大约10个文件。突然我看到关于函数未定义的错误。同时,在模块/软件包的src中明确定义了这些功能(并适当大写)。
我的直觉是这是由于构建顺序所致。假设我们有2个文件“ a.go”和“ b.go”。文件“ a.go”引用了文件“ b.go”中的函数。当在“ b.go”之前构建文件“ a.go”时,出现未定义的错误。我的第二感觉是文件“ a.go”包含对文件“ b.go”内部函数的引用,反之亦然。因此,文件“ b.go”也引用了文件“ a.go”中的函数。
答案 0 :(得分:0)
您可以根据需要在一个目录中包含多达.go
个文件。
Go软件包由一个目录中的所有.go
文件组成。单个目录中的每个.go
文件应与同一目录中的其他package foo
文件具有相同的.go
声明。
您的源代码通过导入语句(例如import "github.com/my/repo/pkg1"
中提供的导入路径从另一个包(另一个目录)中导入代码。
要构建软件包,您可以cd
到目录并发布go build .
(其中.
意味着构建当前目录中的所有文件,或者也可以发布{{ 1}}中没有任何参数,因为默认值为go build
)。
同一包(同一目录)中的代码可以引用同一包(同一目录)中其他文件中的代码,而无需导入其他文件,也不需要导出符号(大写的第一个字符)。 / p>
非常值得花时间阅读"How to Write Go Code",其中包括这些概念的概述,包括:
Go程序员通常将所有Go代码保存在单个工作区中。
- 工作区包含许多版本控制存储库(例如,由Git管理)。
- 每个存储库包含一个或多个包。
- 每个软件包都在一个目录中包含一个或多个Go源文件。
- 软件包目录的路径确定其导入路径。
稍后介绍了“工作区”和GOPATH之间的关系:
GOPATH环境变量指定工作空间的位置。默认情况下,它的目录位于您的主目录内,因此在Unix上为$ HOME / go,在Plan 9上为$ home / go,在Windows上为%USERPROFILE%\ go(通常为C:\ Users \ YourName \ go)。>
关于您更具体的问题:
将单个程序包拆分为多个(许多)文件会在进行构建时产生未定义的错误。/
在同一个目录中的多个单独.
文件中拆分软件包(相同的软件包)本身不会引起问题,但是当然需要正确进行(例如,所有{{1} }同一目录(同一包)中的文件需要在顶部附近具有相同的.go
声明;同一目录中的文件不应尝试使用.go
语句来导入同一目录中的其他文件;等)。
我的直觉是因为构建顺序。
构建顺序在这里无关紧要。
第二个感觉是文件“ a.go”包含对文件“ b.go”内部函数的引用,反之亦然。因此,文件“ b.go”也引用了文件“ a.go”中的函数。
如果package foo
和import
位于同一程序包(同一目录)中,这很好。
另一方面,如果a.go
和b.go
位于不同的程序包(不同的目录)中,则不允许这样做。这是因为Go不允许在包级别使用循环依赖项。如果这是问题所在,那么最简单的解决方案是将a.go
和b.go
移到同一目录中,或者重构以引入第三个包来中断周期,从而使a.go
和{{1 }}都可以依赖于第三个程序包,也可以使用接口或其他可能的解决方案,但是鉴于您说您不熟悉Go,最简单的解决方案可能是学习时最好的解决方案。