一.package
1.实例
Go使用包来组织源码,所有语法的可见性均定义在package这个级别,一般会有一个test文件用于单元测试
每一个包中的go文件可以互相引用其中方法
假设项目顶层目录为./top,在top下创建main.go文件作为程序执行入口(./top/main.go),包名必须是package main
假设有功能A和B分别放在./top/A/a.go和./top/B/b.go下,分别为package A和package B:
// a.go
package A
func a {
...
}
// b.go
package B
func b {
...
}
在main.go中引入a和b函数:
//main.go
package main
import (
"top/A" // import的是目录名
"top/B" // import的是目录名
)
func main() {
A.a() // 这里应用的是包名
B.b()
}
2.包名/路径/目录名/文件名的关系
1.import导入的是相对路径,非package名!
2.习惯上将package名和目录名保持一致,如实例中package A尽量在./top/A文件夹下
3.代码中引用包方法/对象/变量时,如调用package A中的a函数,使用A.a而非目录名
4.同一目录下,所有源文件必须使用相同的包名,一个文件夹下只能有一个package;如果多个文件夹下有同名package,其实只是彼此无关的package,如果需要同时使用不同目录下的同名package,import时需要为每个目录指定package别名:
5.同一package下不同文件间可以直接调用
6.大写字母开头的变量方法暴露到包外,包内大小写随意
7.多个go文件在main包下是无法相互调用的,需要使用go run *.go命令
import (
A1 "top/mid1/A" // package A
A2 "top/mid2/A" // package A
)
3.在package中/间相互引用
见2.6
4.可见性
可见性只针对包,而不针对文件
使用下划线来引入该包,并不使用包内函数,而是仅仅只调用了包内的init()函数,在引入时调用执行init()
二.modules
三.main函数/init函数
若在包中定义init()函数,则该函数会在包引入时执行
main函数和init函数:
相同点:两个函数在定义时不能有任何的参数和返回值。该函数只能由 go 程序自动调用,不可以被引用。
不同点:init 可以应用于任意包中,且可以重复定义多个。main 函数只能用于 main 包中,且只能定义一个。
函数执行顺序:
在 main 包中的 go 文件默认总是会被执行。对同一个 go 文件的init( )调用顺序是从上到下的
对同一个 package 中的不同文件,将文件名按字符串进行“从小到大”排序,之后顺序调用各文件中的init()函数
对于不同的 package,如果不相互依赖的话,按照 main 包中 import 的顺序调用其包中的 init() 函数
如果 package 存在依赖,调用顺序为最后被依赖的最先被初始化,例如:导入顺序 main –> A –> B –> C,则初始化顺序为 C –> B –> A –> main,一次执行对应的 init 方法。main 包总是被最后一个初始化,因为它总是依赖别的包
避免出现循环 import,例如:A –> B –> C –> A。一个包被其它多个包 import,但只能被初始化一次

参考链接: