Go语言中是用包对代码进行组织。
包声明的基本规则
- 同目录下的源码文件的代码包声明语句要一致。也就是说,它们要同属于一个代码包。如果目录中有命令源码文件,那么其他种类的源码文件也应该属于main包。这也是我们能够成功构建和运行它们的前提。
- 源码文件声明的代码包的名称可以与其所在的目录的名称不同(最好相同)。在针对代码包进行构建时,生成的结果文件的主名称与其父目录的名称一致。对于命令源码文件而言,构建生成的可执行文件的主名称会与其父目录的名称相同。
包引用规则
我们创建两个源码文件
%GOPATH%\src\go_code\project01\main\main.go
package main
import (
"flag"
lib5 "go_code/project01/main/lib" //导入库源码文件
)
var name string
func init() {
flag.StringVar(&name, "name", "everyone", "The greeting object.")
}
func main() {
flag.Parse()
//引用库源码文件
lib5.Hello(name)
}
%GOPATH%\src\go_code\project01\main\lib\main_lib.go
package lib5
import "fmt"
func Hello(name string) {
fmt.Printf("Hello, %s!\n", name)
}
导入库源码文件时应该导入%GOPATH%/src下的相对路径。在本示例中,使用其中的程序实体的时候应该以lib5.为限定符。因为我们在源码文件中声明所属的代码包与其所在目录的名称不同,所以导入的时候需要在前面加上lib5,才能正常编译。请记住,源码文件所在的目录相对于 src 目录的相对路径就是它的代码包导入路径,而实际使用其程序实体时给定的限定符要与它声明所属的代码包名称对应。为了不让该代码包的使用者产生困惑,我们总是应该让声明的包名与其父目录的名称一致。
main_lib.go文件中的Hello函数的首字母大写涉及了Go 语言中对于程序实体访问权限的规则。名称的首字母为大写的程序实体才可以被当前包外的代码引用,否则它就只能被当前包内的其他代码引用。通过名称,Go 语言自然地把程序实体的访问权限划分为了包级私有的和公开的。对于包级私有的程序实体,即使你导入了它所在的代码包也无法引用到它。
在 Go 1.5 及后续版本中,我们可以通过创建internal代码包让一些程序实体仅仅能被当前模块中的其他代码引用。这被称为 Go 程序实体的第三种访问权限:模块级私有。
具体规则是,internal代码包中声明的公开程序实体仅能被该代码包的直接父包及其子包中的代码引用。当然,引用前需要先导入这个internal包。对于其他代码包,导入该internal包都是非法的,无法通过编译。