持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情
1. init()的使用
见名知意,init()是Go中的初始化函数。我们都知道,main()函数是Go程序启动的入口,而init()函数就是在main()之前,起到一个初始化的作用。
代码解读
复制代码
package main
import (
"fmt"
)
func main() {
fmt.Println("程序运行......")
}
func init() {
fmt.Println("初始化......")
}
运行结果:
代码解读
复制代码
初始化......
程序运行......
init()的使用非常常见,我们可以在这里进行MySQL,Redis或者MQ等客户端的初始化,方便我们在程序中直接调用次。
2. init()的执行顺序
需要注意的是,每个Go文件中都可以存在多个init()函数,但是统一文件中的init()函数的执行顺序是不固定的。
刚刚我们已经知道了,init()函数是在main()之前运行的,那么多个文件中的init()是怎样的执行顺序呢?
新建两个文件main.go
与called.go
:
代码解读
复制代码
package main
import (
"fmt"
)
func main() {
fmt.Println("程序运行......")
}
func init() {
fmt.Println("初始化......")
}
代码解读
复制代码
package main
import "fmt"
func init() {
fmt.Println("called初始化......")
}
运行main(),输出结果如下:
代码解读
复制代码
called 初始化......
初始化......
程序运行......
我们可以看到,导入的包中的init()是优先于本文件的init()执行的。
另外,变化初始化的过程是先与init()的,整体流程如下图所示:
3. init()与sync.Once对比
在 Go 语言的 sync 包中提供了 sync.Once 原语用于进行运行时的一次性加载过程。
- sync.Once 是在代码运行中需要的时候执行,且只执行一次。
- init() 函数是在文件包首次被加载的时候执行,且只执行一次。
sync.Once 仅提供了一个方法 Do,参数 f 是对象初始化函数,其使用如下所示:
代码解读
复制代码
func ReadConfig() *Config {
once.Do(func() {
var err error
config = &Config{Server: os.Getenv("TT_SERVER_URL")}
config.Port, err = strconv.ParseInt(os.Getenv("TT_PORT"), 10, 0)
if err != nil {
config.Port = 8080 // default port
}
log.Println("init config")
})
return config
}
总的来说,init()的初始化过程更像是饿加载,而sync.Once是懒加载。
作者:树獭叔叔
链接:https://juejin.cn/post/7150558970036355079
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
链接:https://juejin.cn/post/7150558970036355079
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。