#《Go 语音圣经(中文版)》

#程序结构

#包和文件

包级别的名字,例如在一个文件声明的类型和常量,在同一个包的其他源文件也是可以直接访问的,就好像所有代码都在一个文件一样。

包的初始化首先是解决包级变量的依赖顺序,然后按照包级变量声明出现的顺序依次初始化:

1
2
3
4
5
var a = b + c // a 第三个初始化, 为 3
var b = f() // b 第二个初始化, 为 2, 通过调用 f (依赖c)
var c = 1 // c 第一个初始化, 为 1

func f() int { return c + 1 }

Go语言的习惯是在if中处理错误然后直接返回,这样可以确保正常执行的语句不需要代码缩进。

1
2
3
4
5
6
7
8
9
var cwd string

func init() {
cwd, err := os.Getwd() // NOTE: wrong!
if err != nil {
log.Fatalf("os.Getwd failed: %v", err)
}
log.Printf("Working directory = %s", cwd)
}

上面是错误的写法,不会更新全局的cwd变量,而且局部的cwd变量被log.Printf调用也使得定义变量未使用失效了。正确做法:

1
2
3
4
5
6
7
8
9
var cwd string

func init() {
var err error
cwd, err = os.Getwd() // 避免使用 := 的简短声明方式
if err != nil {
log.Fatalf("os.Getwd failed: %v", err)
}
}