init
函数在 Go 语言中具有特殊意义。它在每个包完成初始化后自动执行,但在任何其他函数被调用之前执行。具体来说,init
函数的执行时机如下:
- 当一个包被导入时,首先检查包是否已经导入且被初始化。如果还没有,先对该包的依赖进行初始化。
- 然后,在包级别的变量被初始化后,该包的
init
函数会被调用。这个过程是自动的,并且是在编译时就确定下来的。 - 如果一个包有多个
init
函数(可能分散在包的多个文件中),它们将按照它们在代码中出现的顺序被调用。 - 如果一个包被多个其他包导入,其
init
函数只会被执行一次。
这个机制保证了无论包被导入多少次,init
函数只运行一次,并且在程序的主函数main
运行之前。这样的设计用于执行临时的初始化任务,比如设置包内部的数据结构,初始化变量,或者是注册必要的信息。
例如,如果有一个数据库包,你可能会在init
函数中设置数据库的连接池:
gopackage database import "database/sql" var dbPool *sql.DB func init() { var err error dbPool, err = sql.Open("postgres", "connection_string") if err != nil { log.Fatalf("Database connection failed: %s", err) } } // 其他数据库操作函数...
在这个例子中,无论这个数据库包被导入多少次,或在程序的哪个地方被导入,init
函数都会确保在程序执行任何数据库操作前数据库连接已经设置好。