包package
Go使用包来组织源代码
内置包源码位于
$GOROOT/src
下定义包:
包名一般是小写的,使用一个简短且有意义的名称
包名一般要和所在的目录同名,也可以不同,包名中不能包含
-
等特殊符号一个文件夹下的所有源码文件只能属于同一个包,同样属于同一个包的源码文件不能放在多个文件夹下
包的定义不包含路径,比如定义包:
package myp
,不会定义package ppkg/myp
包名为 main 的包为应用程序的入口包,编译不包含 main 包的源码文件时不会得到可执行文件
包一般使用域名作为目录名称,这样能保证包名的唯一性,比如 GitHub 项目的包一般会放到
GOPATH/src/github.com/userName/projectName
目录下
导入包:
导入包需要带上路径
import ppkg/myp
包名称是从
$GOPATH/src/
下面进行计算的,使用/
分割,import ppkg/myp
的路径实际为$GOPAT/src/ppkg/myp
导入包
// 单行导入
import "包 1. 入门 的路径"
import "包 2 的路径"
// 多行导入
import (
"包 1. 入门 的路径"
"包 2 的路径"
)
// 全路径导入
// 全路径是指GOROOT/src/或GOPATH/src/后面包的存放路径
import "lab/test"
import "database/sql/driver"
import "database/sql
// 相对路径导入
import "../a"
引用包
导入包后,需要对包内的成员进行引用,有以下几种引用方式
标准引用:
package main import "fmt" // 不使用包会报错 func main() { fmt.Println("hello") // 使用包名.成员名称 }
自定义别名引用,当包名称有冲突时使用
package main import F "fmt" // 不使用包会报错 func main() { F.Println("hello") // 使用包别名.成员名称 }
省略引用格式,将包内的内容合并到当前源文件中
package main import . "fmt" // 不使用包会报错 func main() { Println("hello") // 不需要任何前缀,直接使用 }
匿名引用格式,如果只是希望执行包初始化的 init 函数,而不使用包内部的数据时,可以使用匿名引用格式,即使不使用包也不会报错
package main import ( _ "database/sql" // 即使不使用包,也不会报错 "fmt" ) func main() { fmt.Println("C语言中文网") }
init函数
一个包可以有多个 init 函数,包加载时会执行全部的 init 函数,但并不能保证执行顺序,所以不建议在一个包中放入多个 init 函数,将需要初始化的逻辑放到一个 init 函数里面。
包不能出现环形引用的情况,比如包 a 引用了包 b,包 b 引用了包 c,如果包 c 又引用了包 a,则编译不能通过。
包的重复引用是允许的,比如包 a 引用了包 b 和包 c,包 b 和包 c 都引用了包 d。这种场景相当于重复引用了 d,这种情况是允许的,并且 Go 编译器保证包 d 的 init 函数只会执行一次。
main包中的init函数将会先于main函数运行。
package main import "fmt" func init() { fmt.Println("init") } func main() { fmt.Println("Hello") } // 运行结果 // init // Hello
包加载

Go语言包的初始化有如下特点:
包初始化程序从 main 函数引用的包开始,逐级查找包的引用,直到找到没有引用其他包的包,最终生成一个包引用的有向无环图。
Go 编译器会将有向无环图转换为一棵树,然后从树的叶子节点开始逐层向上对包进行初始化。
单个包的初始化过程如上图所示,先初始化常量,然后是全局变量,最后执行包的 init 函数。
导出标识符
标识符包含变量、常量、方法等,只需要将其首字母大写即可导出:
package mypkg
var myVar = 100
const MyConst = "hello"
type MyStruct struct {
}
如果结构体或者函数中的值也想导出,也将标识符首字母大写即可:
type MyStruct struct {
// 包外可以访问的字段
ExportedField int
// 仅限包内访问的字段
privateField int
}
type MyInterface interface {
// 包外可以访问的方法
ExportedMethod()
// 仅限包内访问的方法
privateMethod()
}
最后更新于
这有帮助吗?