【Go】go init函数

一、前言

之前有一次我在写程序的时候,创建了一个init函数func init(),起初我并不知道init()是go本身自带的一个函数,类似于main(),于是我给init()函数设置返回值时,Goland提示错误,当时很纳闷,百度了才知道这回事。

由此,写一篇博客,以记录init()函数用法。

二、init函数介绍

init()函数是一个特殊的函数,存在以下特性:

  1. 不能被其他函数调用,而是在main函数执行之前,自动被调用
  2. init函数不能作为参数传入
  3. 不能有传入参数和返回值

以下是《the way to go》中的解释:

变量除了可以在全局声明中初始化,也可以在 init ()函数中初始化。这是一类非常特殊的函数,它不能够被人为调用,而是在每个包完成初始化后自动执行,并且执行优先级比 main 函数高。

每个源文件都只能包含一个 init() 函数(此处存在错误)。初始化总是以单线程执行,并且按照包的依赖关系顺序执行。

一个可能的用途是在开始执行程序之前对数据进行检验或修复,以保证程序状态的正确性。

1、每个源文件能包含多个init函数

package main

import "fmt"
//经测试,每个源文件可以包含多个init函数,而且会按先后顺序执行,优先级高于main
func main() {
	fmt.Println("main")
}

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

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

上述程序的运行结果是:

init1
init2
main

2、导包顺序决定init函数执行顺序

go中不同包中init函数的执行顺序是根据包的导入关系决定的。

//=====================main包
package main

import (
	"fmt"
	_ "mytest/level1"
)

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

//=====================level1包
package level1

import (
	"fmt"
	_ "mytest/level2"
)

func init() {
	fmt.Println("level1 init")
}
//=====================level2包
package level2

import "fmt"

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

从以上代码可以看出,main包导入level1包,而在level1包内导入level2包。

执行结果:

level2 init
level1 init
main

下图(图源自网络)可以总结这种顺序关系

在这里插入图片描述

三、init函数的应用场景举例

1、对变量进行初始化

package trans

import "math"

var Pi float64

func init() {
   Pi = 4 * math.Atan(1)
}

2、当一个程序开始之前调用后台执行的 goroutine

func init() {
   go backend()
}

3、用于注册驱动

//=====================postgres包
package postgres
import (
    "database/sql"
    "database/sql/driver"
    "errors"
)
// PostgresDriver provides our implementation for the
// sql package.
type PostgresDriver struct{}
// Open provides a connection to the database.
func (dr PostgresDriver) Open(string) (driver.Conn, error) {
    return nil, errors.New("Unimplemented")
}
var d *PostgresDriver
// init is called prior to main.
func init() {
    d = new(PostgresDriver)
    sql.Register("postgres", d)
}
//=====================main包
package main

import (
    "database/sql"
    _ "github.com/goinaction/code/chapter3/dbdriver/postgres"
)

func main() {
    sql.Open("postgres", "mydb")
}
  • 10
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值