Go语言的坑: Init 函数

Go语言的坑: Init 函数

[toc]

init 函数会在全局变量之后被执行

init 函数并不是最先被执行的,如果声明了 const 或全局变量,那么 init 函数会在它们之后执行:

package main

import "fmt"

var a = func() int {
  fmt.Println("a")
  return 0
}()

func init() {
  fmt.Println("init")
}

func main() {
  fmt.Println("main")
}

// output
a
initmain

init 初始化按解析的依赖关系顺序执行

比如 main 包里面有 init 函数,依赖了 redis 包,main 函数执行了 redis 包的 Store 函数,恰好 redis 包里面也有 init 函数,那么执行顺序会是:

还有一种情况,如果是使用 “import _ foo” 这种方式引入的,也是会先调用 foo 包中的 init 函数。

扰乱单元测试

比如我们在 init 函数中初始了一个全局的变量,但是单测中并不需要,那么实际上会增加单测得复杂度,比如:

var db *sql.DB
func init(){
  dataSourceName := os.Getenv("MYSQL_DATA_SOURCE_NAME")
    d, err := sql.Open("mysql", dataSourceName)
    if err != nil {
        log.Panic(err)
    }
    db = d
}

在上面这个例子中 init 函数初始化了一个 db 全局变量,那么在单测的时候也会初始化一个这样的变量,但是很多单测其实是很简单的,并不需要依赖这个东西。

Licensed under CC BY-NC-SA 4.0
Built with Hugo
主题 StackJimmy 设计