包
在 Go 语言里,包是个非常重要的概念。其设计理念是使用包来封装不同语义单元的功能,更好地复用代码,并对每个包内的数据的使用有更好的控制。
包的规则
- 所有的.go 文件,除了空行和注释,都应该在第一行声明自己所属的包。
- 每个包都在一个单独的目录里。
- 不能把多个包放到同一个目录中,也不能把同一个包的文件分拆到多个不同目录中。
- 这意味着,同一个目录下的所有.go 文件必须声明同一个包名。
包的命名
- 给包命名的惯例是使用包所在目录的名字
- 给包及其目录命名时,应该使用简洁、清晰且全小写的名字
记住:并不需要所有包的名字都与别的包不同,因为导入包时是使用全路径的,所以可以区分同名的不同包。一般情况下,包被导入后会使用你的包名作为默认的名字,不过这个导入后的名字可以修改。
main包
在 Go 语言里,命名为 main 的包具有特殊的含义。 Go 语言的编译程序会试图把这种名字的包编译为二进制可执行文件。所有用 Go 语言编译的可执行程序都必须有一个名叫 main 的包。
包的导入
导入包需要使用关键字import ,它会告诉编译器你想引用该位置的包内的代码。如果需要导入多个包,习惯上是将 import 语句包装在一个导入块中。
import (
"fmt"
"strings"
)
编译器查找packge的顺序:
- 标准库,如
/usr/local/go/src/*/*
,这个路径由环境变量GOROOT决定。 - 当前项目源代码路径,如
/home/myproject/src/*/*
- gopath路径,如
/home/sky/work/soft/go/*/*
,这个路径由环境变量GOPATH决定。
查找策略:一旦编译器找到一个满足 import 语句的包,就停止进一步查找。
远程导入
Go 支持从远程网站获取源代码,如github:
import "github.com/spf13/viper"
获取过程使用 go get
命令完成
命名导入
重名的包可以通过命名导入来导入。
命名导入是指,在 import 语句给出的包路径的左侧定义一个名字,将导入的包命名为新名字。
import (
"fmt"
myfmt "mylib/fmt"
)
导入一个不在代码里使用的包时,Go 编译器会编译失败,输出错误。这个特性可以防止导入了未被使用的包,避免代码变得臃肿。
如果需要导入一个包,但是不需要引用这个包的标识符。在这种情况,可以使用空白标识符_
来重命名这个导入:
import (
_ "mylib/fmt"
)
init函数
每个包可以包含任意多个 init 函数,这些函数都会在程序执行开始的时候被调用。
多个init函数之间的执行顺序不定,不要依赖这个顺序。
所有被编译器发现的 init 函数都会安排在 main 函数之前执行。
init 函数用在设置包、初始化变量或者其他要在程序运行前优先完成的引导工作。