包和文件
Go 文件中的内部信息, 根据是否大写字母开头判断是否导出
|
|
按照惯例,一个包的名字和包的导入路径的最后一个字段相同,例如gopl.io/ch2/tempconv包的名字一般是tempconv。
如果导入了一个包,但是又没有使用该包将被当作一个编译错误处理。这种强制规则可以有效减少不必要的依赖
使用
golang.org/x/tools/cmd/goimports
自动添加删除导入包
包的初始化
包的初始化首先是解决包级变量的依赖顺序,然后按照包级变量声明出现的顺序依次初始化:
|
|
如果包中含有多个.go源文件,它们将按照发给编译器的顺序进行初始化,Go语言的构建工具首先会将.go文件根据文件名排序,然后依次调用编译器编译。
init 函数特点
init
优先于main
自动执行 , 不能被其它函数调用- 每个包可以有多个
init
函数 - 导入包前缀加上
_
仅执行 该包的 全局变量初始化和init
- 无参数声明和结果声明
- 在每个文件中的init初始化函数,在程序开始执行时按照它们声明的顺序被自动调用。
注 : 程序不应该依赖各个包的 init
的执行顺序
init 常用用途
实现包级变量复杂初始化,注: 尽量不要使用 init 函数来初始化包级变量,如无必要,不要使用 init 函数,减少代码复杂性。
|
|
注册模式
利用 _
导入,会使导入的依赖初始化,如 pg 包中实现的驱动注册。
通过在 init 函数中注册自己的实现的模式,有效降低了 Go 包对外的直接暴露。
|
|
Go 程序初始化流程
- 初始化导入的包 , 没有依赖的包优先初始化
- 初始化有依赖的包
- 初始化没有依赖的常量 , 变量
- 初始化有依赖的常量 , 变量
- 执行
init
函数 - 执行
main
函数
作用域
当编译器遇到一个名字引用时,它会对其定义进行查找,查找过程从最内层的词法域向全局的作用域进行。如果查找失败,则报告“未声明的名字”这样的错误。如果该名字在内部和外部的块分别声明过,则内部块的声明首先被找到。在这种情况下,内部声明屏蔽了外部同名的声明,让外部的声明的名字无法被访问
for
循环有显示词法域和隐式词法域 , 显示词法域是花括号里代码块 , 隐式词法域是 i:=0
初始化
和for循环类似,if和switch语句也会在条件部分创建隐式词法域,还有它们对应的执行体词法域。
switch语句的每个分支也有类似的词法域规则:条件部分为一个隐式词法域,然后是每个分支的词法域。
|
|
一个错误的演示
|
|
你可以这样干, 但是不推荐
|
|
对于变量的初始化 , 如果要处理错误 , 不建议直接声明赋值 , 而是这样做
|
|
不建议的
var cwd,_ = os.GetWd()
正确的做法
|
|