内容简介:package组织go代码的一种形式,和python ,Java,c++等语言的包是具有同样的功能,在使用其他包的函数和结构体,变量时,必须先引入package的文件,package是定义方的语句,而import是使用方的语句。有时在package的文件中,能看到init函数,这种函数一般函数不一样,无法被调用(无论是包内还是包外)。init函数只在该文件被被引用时才执行(是import时,不是调用包函数时)。在go中,init和main函数都是特殊的存在,两者都不能定义参数和返回值,否则编译器直接报错。i
一、package 和init函数
package组织 go 代码的一种形式,和python ,Java,c++等语言的包是具有同样的功能,在使用其他包的函数和结构体,变量时,必须先引入package的文件,package是定义方的语句,而import是使用方的语句。有时在package的文件中,能看到init函数,这种函数一般函数不一样,无法被调用(无论是包内还是包外)。init函数只在该文件被被引用时才执行(是import时,不是调用包函数时)。
二、init函数的特殊性
在go中,init和main函数都是特殊的存在,两者都不能定义参数和返回值,否则编译器直接报错。init函数在同一个包内,同一个文件内都可以定义多个init函数,且在包依赖情况时,会优先执行依赖包的init函数。具体如下:
- init函数是用于程序执行前做包的初始化的函数,比如初始化包里的变量等
- 每个包可以拥有多个init函数
- 包的每个源文件也可以拥有多个init函数
- 同一个包中多个init函数的执行顺序go语言没有明确的定义(说明)
- 不同包的init函数按照包导入的依赖关系决定该初始化函数的执行顺序
- init函数不能被其他函数调用,而是在main函数执行之前,自动被调用
三、init的执行顺序
init的执行顺序按照以下几个原则:
- 依赖包的init函数先执行,比如A 依赖于B,那么B的init函数先执行
- 不同包被引入的,按照引入的顺序执行
- 同一文件内的多个init函数,按照函数定义的顺序执行
- 引用包的init函数优先于 本文件内的init函数执行
demo:
package main import ( "Test/lib" "fmt" ) func init() { fmt.Println("hello world") } func main() { fmt.Println("wint") lib.Mutable() lib.UnMutable() }
lib库函数
package lib import "fmt" func init() { fmt.Println("empty init load 123") } func init() { fmt.Println("empty init load") } func Mutable() { var i = 1 var b = true var f = 1.3 var s = "hello world" fmt.Printf("%p, %p, %p, %p\n", &i, &b, &f, &s) i = 2 b = false f = 1.4 s = "hello me" fmt.Printf("%p, %p, %p, %p\n", &i, &b, &f, &s) } func UnMutable() { type S struct { Name string Index int } var m = map[string]string{ "name": "map", "type":"map string", } var s = S { Name: "struct", Index : 1, } fmt.Printf("%p, %p\n", &m, &s) m["name"] = "map change" s.Name = "struct change" fmt.Printf("%p, %p\n", &m, &s) }
//输出内容 empty init load 123 empty init load hello world wint 0xc00008c020, 0xc00008c028, 0xc00008c030, 0xc0000800a0 0xc00008c020, 0xc00008c028, 0xc00008c030, 0xc0000800a0 0xc00007c020, 0xc000088040 0xc00007c020, 0xc000088040
四、init的几个建议
init虽说是golang的一个特性,但也有一些不足,根据之前的经验总结如下:
- 尽量不要让init执行过多的程序,因为init是隐式执行的,如果过多代码执行,会造成程序不可控,一些隐藏问题无法快速发现
- 不要在文件内,定义多个init函数,防止init混乱问题,同时减少定义顺序带来的不可控问题
- 尽可能使用显示Init函数代替init函数,让调用方清楚知道被调用方做的申请。比如InitConn,可看出是初始化某个连接,这样在使用结束时,可显示释放连接。
- init中的全局变量注意要释放,否则在默认初始化后,没有即使得到释放,可能会造成资源占满情况出现。比如 mysql 连接。
以上所述就是小编给大家介绍的《特殊的init函数》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Python 拓展之特殊函数(lambda 函数,map 函数,filter 函数,reduce 函数)
- Python 函数调用&定义函数&函数参数
- python基础教程:函数,函数,函数,重要的事说三遍
- C++函数中那些不可以被声明为虚函数的函数
- 017.Python函数匿名函数
- 纯函数:函数式编程入门
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。