包是函数和数据的集合,将有相关特性的函数和数据放在统一的文件/目录进行管理,每个 包都可以作为独立的单元维护并提供给其他项目进行使用
1.声明
Go源文件都需要在开头使用 package 声明所在包,包名告知编译器哪些是包的源代码用于编译库文件,其次包名用于限制包内成员对外的可见性,最后包名用于在包外对公开成员的访问。
包名使用简短的小写字母,常与所在目录名保持一致,一个包中可以由多个Go源文件,但必须使用相同包名。
2.导入&调用
在使用包时需要使用import将包按路径名导入,再通过包名调用成员,可通过import每行导入一个包,也可使用括号包含所有包并使用一个import导入
工作目录结构说明:
- bin: 用于放置发布的二进制程序;
- pkg: 用于放置发布的库文件;
- src: 用于放置源代码;
编译&运行:
使用 go build 编译二进制文件
命令:go build gpkgmain
说明:编译路径gpkgmain下的包,main包,则在当前目录产生以pkgmain命令的二进制程序使用 go run 运行二进制文件
命令:go run gpkgmain使用 go install 编译并发布二进制文件
命令:go install pgkgmain
说明:编译并发布路径gpkgmain下的包,main包,则在将编译后的以pkgmain命令的二进制程序拷贝到bin目录使用 go install 编译发布库文件
命令:go install gpkgname/pkg01
说明:编译并发布路径pgkgname/pkg01下的包,非main包,则在将编译的以包名命名的库文件拷贝到pkg/GOOS_GOARCH目录下使用 go install 编译发布所有二进制和库文件
命令:go install ./…
说明:编译并发布当前路径下的所有二进制程序和库文件
注意:Go语音不允许交叉导入包
3.导入形式
- 绝对路径倒入,在GOPATH目录中查找包:
import "fmt" import "gpkgname/pgk01"
- 相对路径导入,在当前文件所在的目录查找
import "./gpkgname/pkg02"
- 点导入,在调用点导入包中的成员时可以直接使用成员名称进行调用(省略包名)``` package main
import . “fmt”
func main() { Println(“Hi”) }
4. 别名导入,当导入不通路径的相同包名时,可以别名导入为包重命名,避免冲突
pakcage main
import f “fmt”
func main() { f.Println(“hi”) }
5. 下划线导入,Go不允许导入但未使用,在某些情况下需要初始化包,使用空白符作为别名进行导入,从而使用包中的初始化函数可以执行:
package main
import _ “fmt”
func main() {
}
<a name="af0ad68b"></a>
### 4.成员可见性
Go语言使用名称首字母大小写来判断对象(常量、变量、函数、类型、结构体、方法等)的访问权限,首字母大写标识包外可见(公开的),否者仅包内可访问(内部的)
pakcage pkg01
// public var Name string = “pkg01”
// private var version string = “1.0” ```
5.main包与main函数
main包用于声明告知编译器将包编译为二进制可执行文件,在main包中的main函数是程序的入口,无返回值,无参数
6.init函数
init函数是初始化包使用,无返回值,无参数。建议每个包只定义一个。init函数在import包时自动被调用(const —> var —> init)
7.Go包管理
7.1 介绍
Go1.11版本提供Go modules机制对包进行管理,同时保留GOPATH和vendor机制,使用临时环境变量GO111MODULE进行控制,GO111MODULE有三个可选值:
- 当GO111MODULE为off时,构建项目始终在GOPATH和vendor目录搜索目标程序依赖包;
- 当GO111MODULE为on时,构建项目则始终使用Go modules机制,在GOPATH/pkg/mod目录搜索目标程序依赖包;
- 当GO111MODULE为auto(默认)时,当构建源代码不在GOPATH/src的子目录且包含go.mod文件,则使用Go modules机制,否则使用GOPATH和vendor机制
7.2 GOPATH+vendor机制
vendor
将项目依赖包拷贝到项目下的vendor目录,在编译时使用项目下vendor目录中的包进行编译,解决问题:- 依赖外部包过多,在使用第三方包时需要使用go get进行下载
- 第三方包在go get下载后不能保证开发和编译时版本的兼容性
包搜索顺序
- 在当前包下的vendor目录查找
- 向上级目录查找,知道GOPATH/src/vendor目录
- 在GOPATH目录查找
- 在GOROOT目录查找
第三方包
可以借助go get工具下载和安装第三方包及其依赖,需要安装与第三方包匹配的代码管理工具,比如git、svn等;
常用参数:- -d: 仅下载依赖包
- -u: 更新包并安装
- -x: 打印执行的命令
- -v: 打印构建的包
-insecure: 允许使用http协议下载包
- https://gowalker.org
7.3 Go modules机制
优势:
- 不用设置GOPATH,代码可任意放置
- 自动下载依赖管理
- 版本控制
- 不允许使用相对导入
- replace机制
初始化模块:go mod init modname
对于当前模块下的包导入时需要使用modname+packagename
第三方包:在使用go mod tidy、go build、go test、go list命令会自动将第三方依赖写入到go.mod文件中同时下载第三方依赖包到GOPATH/pkg/mod/cache目录,并在当前模块目录生成一个构建状态跟踪文件go.sum,文件中记录当前module所有的顶层和间接依赖,以及这些依赖的校验和;
常用命令:
go mod tidy: 整理依赖模块(添加新增的,删除未使用的)
go mod vendor: 将依赖模块拷贝到模块中的vendor目录
go build: 编译当前模块
go build ./…: 编译当前目录下的所有模块
go build -mod=vendor: 使用当前模块下的vendor目录中的包进行编译
go mod download: 仅下载第三方模块
go mod grapha: 打印所有第三方模块
go list -m -json all: 显示所有模块信息
go mod edit: 修改go.mod文件
-require=package@version
-replace=old_package@version=new_package@version
可以使用-replace功能将包替换为本地包,实现相对导入
8.标准包
Go提供了大量标准包,可查看:https://golang.google.cn/pkg
- godoc工具:使用godoc命令可以在本地启动golang网站,用户本地查看帮助手册
- go list std: 查看所有标准包
- go doc packagename: 查看包的帮助信息
- go doc packagename.element: 查看包内成员帮助信息