GO 程序初始化

104 阅读2分钟

程序执行顺序

image.png

图片来源:极客时间《Tony Bai · Go 语言第一课》

package main

import (
	"fmt"
	_ "github.com/ChanceXin/test-init-order/pkg1"
	_ "github.com/ChanceXin/test-init-order/pkg2"
)

var (
	_  = constInitCheck()
	v1 = variableInit("v1")
	v2 = variableInit("v2")
)

const (
	c1 = "c1"
	c2 = "c2"
)

func constInitCheck() string {
	if c1 != "" {
		fmt.Printf("main : c1 has been init...")
	}
	if c2 != "" {
		fmt.Printf("main : c2 has been...")
	}

	return ""
}

func variableInit(name string) string {
	fmt.Printf("main : var %s has been... \n", name)
	return name
}

func init() {
	fmt.Printf("main : first init() has been...\n")
}

func init() {
	fmt.Printf("main : second init() has been\n")
}

func main() {
	
        fmt.Println("main : main.main() has been....")
}

package pkg1

import (
	"fmt"
	_ "github.com/ChanceXin/test-init-order/pkg2"
)

const (
	c = "c"
)

var (
	_ = constInitCheck()
	v = variableInit("v")
)

func constInitCheck() string {
	if c != "" {
		fmt.Printf("pkg1 : c has been init...\n")
	}
	return ""
}

func variableInit(name string) string {
	fmt.Printf("pkg1 : var %s has been... \n", name)
	return name
}

func init() {
	fmt.Printf("pkg1 :first init() has been...\n")
}

func init() {
	fmt.Printf("pkg1 : second init() has been\n")
}

package pkg2

import (
	"fmt"
)

const (
	c = "c"
)

var (
	_ = constInitCheck()
	v = variableInit("v")
)

func constInitCheck() string {
	if c != "" {
		fmt.Printf("pkg2 : c has been init...\n")
	}
	return ""
}

func variableInit(name string) string {
	fmt.Printf("pkg2 : var %s has been... \n", name)
	return name
}

func init() {
	fmt.Printf("pkg2 :first init() has been...\n")
}

func init() {
	fmt.Printf("pkg2 : second init() has been\n")
}

输出结果:

pkg2 : c has been init...
pkg2 : var v has been... 
pkg2 : first init() has been...
pkg2 : second init() has been
pkg1 : c has been init...
pkg1 : var v has been... 
pkg1 : first init() has been...
pkg1 : second init() has been
main : c1 has been init...main : c2 has been...main : var v1 has been... 
main : var v2 has been... 
main : first init() has been...main : second init() has been
main : main.main() has been....

入口函数 main包的main函数

其他包中也可以有main函数,但因为是小写字母开头,所以只能在包内使用 main.main函数 运行在主Goroutine(go 中的用户级线程实现)中,main函数返回意味整个go程序的结束。

init函数

执行在main函数之前,不可显示调用,可定义多个,顺序执行,仅被执行一次。

  • 作用一:重置包级变量值
  • 作用二:包级变量的复杂初始化
  • 作用三:实现“注册模式” 空导入包,会执行init函数,可利用该机制执行“注册”驱动,init()函数无法显示调用,通过该方式避免了包级变量在外部被调用改变。

init 函数十分适合包级数据初始化、包级数据初始状态的检查