亲宝软件园·资讯

展开

Go 入口函数和包初始化

小菠萝测试笔记 人气:0

包 package

main.main 函数:Go 应用的入口函数

package main

package main

func main() {    
    // 用户层执行逻辑
    ... ...
}

Go 语言要求:可执行程序的 main 包必须定义 main 函数,否则 Go 编译器会报错

注意

main 包是不可以像标准库 fmt 包那样被导入(Import)的

其他包也可以拥有 main 函数或方法

按照 Go 的可见性规则(小写字母卡头的标识符为非导出标识符),非 main包中自定义的 main 函数仅限于包内使用

package pkg1

import "fmt"

func Main () {
    main()
}

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

重点

引子

不过对于 main 包的main 函数来说,还需要明确一点,就是它虽然是用户层逻辑的入口函数,但它却不一定是用户层第一个被执行的函数。这是为什么呢?这跟 Go 语言的另一个函数 init 有关

init 函数:Go 包的初始化函数

和 main.main 函数一样,init 函数也是一个无参数无返回值的函数

func init() {
	// 包初始化逻辑
	... ...
}

和 main 函数不一样

init 函数的执行顺序

Go 包的初始化次序

三步走

init 函数的特点

init 函数的用途

重置包级变量值

init 函数就好比 Go 包真正投入使用之前唯一的“质检员”,负责对包内部以及暴露到外部的包级数据(主要是包级变量)的初始状态进行检查

实现对包级变量的复杂初始化

有些包级变量需要一个比较复杂的初始化过程,有些时候,使用它的类型零值或通过简单初始化表达式不能满足业务逻辑要求,而 init 函数则非常适合完成此项工作,标准库 http 包中就有这样一个典型示例

package main

import (
	"os"
	"strings"
)

var (
	http2VerboseLogs    bool // 初始化默认值 false
	http2logFrameWrites bool
	http2logFrameReads  bool
	http2inTests        bool
)

func init() {
	e := os.Getenv("GODEBUG")
	if strings.Contains(e, "http2debug=1") {
		http2VerboseLogs = true // 在 init 中对 http2VerboseLogs 的值进行重置
	}
	if strings.Contains(e, "http2debug=2") {
		http2logFrameWrites = true
		http2logFrameReads = true
		http2inTests = true
	}
}

http 包在init 函数中,就根据环境变量 GODEBUG 的值,对这些包级开关变量进行了复杂的初始化,从而保证了这些开关变量在 http 包完成初始化后,可以处于合理状态

在 init 函数中实现“注册模式”

来看一段使用 lib/pq 包访问 PostgreSQL 数据库的代码

加载全部内容

相关教程
猜你喜欢
用户评论