init函数 


 每一个源文件都可以包含一个init函数,该函数会在main函数执行前,被Go运行框架调用,也就是说init会在main函数前被调用。

main函数和init函数相同点都是没有入参,而且没有返回值。 

package main

import "fmt"

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

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

init
main

通常可以在init函数当中完成初始化的工作

init初始化一般用于哪些场景,比如db的包,那么init函数一般是去做数据库连接等。比如导入db等包,里面有初始化函数,这个初始化函数就是用来连接数据库等。

细节讨论:

1)如果一个文件同时包含全局变量定义,init函数和main函数,则执行的流程是全局变量定义->init函数->main函数,也就是全局变量的定义是最先执行的

2)init函数最主要的作用,就是完成一些初始化的工作,比如下面的案例:

初始化变量在其他包中使用。

package test

var Age int
var Name string

func init() {
	Age = 10
	Name = "hello"
}

3)面试题:案例如果main.go和utils.go都含有变量定义,init函数时,执行的流程又是怎么样的呢?

首先执行被引入文件当中的变量定义,然后执行被引入文件的init函数,最后执行main里面。 

init函数和main函数的异同


相同点: 两个函数在定义时不能有任何的参数和返回值,且Go程序自动调用。

不同点:
  • init可以应用于任意包中,且可以重复定义多个。
  • main函数只能用于main包中,且只能定义一个。
两个函数的执行顺序:
  • 对同一个go文件的 init() 调用顺序是从上到下的。
  • 对同一个package中不同文件是按文件名字符串比较“从小到大”顺序调用各文件中的 init() 函 数。
  • 对于不同的 package ,如果不相互依赖的话,按照main包中"先 import 的后调用"的顺序调用 其包中的 init() ,如果 package 存在依赖,则先调用最早被依赖的 package 中的 init() ,最后调用 main 函数。

main函数


main 包用于声明告知编译器将包编译为二进制可执行文件 ,在 main 包中的 main 函数是程序的入口,无返回值,无参数。
main函数也常常写在main包里面,在其他地方不写。(在其他包里面是不写main函数的)

init 函数


go语言中 init函数用于包 (package)的初始化,该函数是go语言的一个重要特性。

有下面的特征:
  • init函数是用于程序执行前做包的初始化的函数,比如初始化包里的变量等(变量常量等声明和数据库 redis 中间件等连接)
  • 每个包可以拥有多个init函数
  • 同一个包中多个init函数的执行顺序go语言没有明确的定义(实际上是按照顺序执行等)
  • 不同包的init函数按照包导入的依赖关系决定该初始化函数的执行顺序
  • init函数不能被其他函数调用,而是在main函数执行之前,自动被调用

init 函数是初始化包使用,无返回值,无参数。建议每个包只定义一个。init 函数在 import

包时自动被调用(const->var->init)。
初始化函数就是在导入包的时候执行的

_用来做初始化导入的 

可以看到main里面什么都没有,但是却打印了init函数里面的语句。

程序执行的时候加载main包,main里面再去加载其他的,在main里面从上到下加载程序,先去加载程序,在加载程序的时候发现import了,这个时候要去找import包并且进行加载。

在找到包进行加载的时候也会从上到下依次进行加载,如果包里面有import那么还会去加载其他的。因为一个包下面有很多go文件,所以在加载的时候会把这些文件都加载进来。加载完之后会看一下有哪些init函数,然后执行所有的init函数,执行完所有init那么第一个import导入工作就算完成了。

import完之后就会执行main函数的加载,如果main包中还有init函数那么也先执行init函数初始化,执行完之后才会执行main函数。(一个包里面可以包含多个init函数)

如果有在一个包下面有多个go文件,里面都有init这个函数,那么执行顺序是随机的。

init可以用在比如后面和数据库相关的时候,将连接初始化一下,同时初始化一些驱动也是这个原理。

后面还有很多包使用下划线_来导入的,其实就是执行一下包里面的init函数,并不会去使用包名+方法。