「这是我参与2022首次更文挑战的第22天,活动详情查看:2022首次更文挑战」
什么是包
Go 支持良好的软件工程实践。
高质量软件的一个重要组成就是代码重用,体现了软件工程中不要重复“Don't Repeat Yourself”的原则。
函数其实就是代码复用的第一个方法。Go 也提供了另一种支持代码复用的机制:包 package
可以把相关关的 Go 源代码组织到同一单元中,使他们模组化、可重复使用和可维护。。
每一个 Go 文件都隶属于某个包,如下图所示:
package <packagename>
截至目前,我们几乎所有的文章中的程序都包括如下的一行:
import "fmt"
fmt
是一个包的名字,包括各种与 格式化和 屏幕输出 相关的函数。 fmt
是一个核心函式库,包含格式化和打印输出或从各种 I/O 中读取输入等相关的功能。它包括 Println()
、 Printf()
、 Scan()
等函数,以供其他 package 重复使用。
包组织的优点
通过包来组织代码有 3 个目的:
- 减少出现重复命名的冲突,保证函数名称保持简短和简洁。
- 帮助组织不同代码,以便你更容易找到想重用的代码。
- 通过简单的限制重编译程序的一小部分,加快编译的速度。尽管我们使用
fmt
包,但是当我们改变我们的程序时,无需每次都重新编译。
创建一个包
使用GOPATH的工程结构
在 GOPATH 指定的工作目录下,代码总是会保存在 $GOPATH/src
目录下。在工程经过 go build
、 go install
或 go get
等指令后,会将产生的二进制可执行文件放在 $GOPATH/bin
目录下,生成的中间缓存文件会被保存在 $GOPATH/pkg
下。
如果需要将整个源码添加到版本管理工具(Version Control System,VCS)中时,只需要添加 $GOPATH/src
目录的源码即可。bin 和 pkg 目录的内容都可以由 src 目录生成。
包只有在使用它们的独立程序的背景下才真正有意义。没有这个独立的程序,我们就没有办法使用我们创建的包。
让我们创建一个应用程序,它将使用我们将要编写的包。在我们的本地 GOAPTH 中创建一个 包,如C:\Program Files\Go\src\learninggo
中创建一个名为 sort
的文件夹。在该文件夹中创建一个文件叫做 sort.go
,其中包含以下内容,我们可以把我们学过的排序算法的代码单独创建一个自己的排序包,这里值简单以冒泡排序为例:
没有看过这篇文章的推荐看看:跟着动画学Go数据结构之冒泡排序 #私藏项目实操分享#
package sort
func BubbleSortImproved(nums []int, length int) {
swapped := true
for i := 0; i < length-1; i++ {
for j := 0; j < length-i-1; j++ {
if nums[j] > nums[j+1] { // 如果大,交换
var temp = nums[j] // 临时变量保存前一个值
nums[j] = nums[j+1]
nums[j+1] = temp
swapped = false
}
}
if swapped {
break
}
}
}
使用终端进入 sort
文件夹,我们能看到刚才创建的 sort.go
文件,使用 go install
命令,然后我们的包就被编译器创建一个链接对象文件到这个路径:
C:\Program Files\Go\pkg\windows_amd64\learninggo\sort.a
C:\Program Files\Go\src\learninggo\sort
λ go install
所以当执行 go install app
命令时,系统就会在 GOPATH 中寻找 src 目录里的 app 子目录。当编译这个包的时候,就会在 bin 目录下创建名为 app 的二进制文件。由于 bin 目录是在 PATH 中的,所以可以通过终端执行其中的文件。
执行 go install 命令后,系统会尝试在指定的包目录里寻找带有 main
包声明的文件。找到之后,Go 就知道这是可执行的程序,需要被编译为二进制文件。一个包里可以有很多文件,但是只能其中一个文件里有 main 函数,标志着这个文件是程序的入口文件。
然后回到我们本地工作的文件夹 Pakcakes
,创建一个 main.go
,在程序中导入我们自己创建的包:
package main
import "fmt"
import "learninggo/sort"
func main() {
arrays := []int{8, 5, 4, 2, 7, 6, 1, 3}
length := len(arrays)
sort.BubbleSortImproved(arrays, length)
for i := 0; i < len(arrays); i++ {
fmt.Println(arrays[i])
}
}
运行代码,结果如下:
[Running] go run "e:\Coding Workspaces\LearningGoTheEasiestWay\Packages\main.go"
1
2
3
4
5
6
7
8
安装第三方包
go get -u github.com/xxx
上面这个命令的意思是,从 http://github.com/xxx
URL 中引用文件,并保存到 src/github.com/xxx
目录中。根据嵌套包的原则,可以像下面这样引用 xxx
包。
总结
你可能已经注意到,我们所看到的软件包中的每个函数都以大写字母开头。在 Go 中,如果某个东西以大写字母开头,就意味着其他包(和程序)能够看到它。如果我们把函数命名为 bubbleSortImproved 而不是 BubbleSortImproved,我们的主程序就无法看到它了。
这是一个很好的做法,只公开我们的软件包中我们希望其他软件包使用的部分,而隐藏其他的部分。这使我们能够自由地改变这些部分,而不需要别人担心会破坏其他程序,而且它让我们的包更容易使用。
包的名称应该与它们所在的文件夹相匹配。有一些方法可以解决这个问题,但如果你遵循这个规则,会容易得多。
文章灵感来源:https://learnku.com/go/t/27649