main
函数和init
函数
Go里面有两个保留的函数:init
函数(能够应用于所有的package
)和main
函数(只能应用于package main
)。这两个函数在定义时不能有任何的参数和返回值。虽然一个package
里面可以写任意多个init
函数,但这无论是对于可读性还是以后的可维护性来说,我们都强烈建议用户在一个package
中每个文件只写一个init
函数。Go程序会自动调用init()
和main()
,所以你不需要在任何地方调用这两个函数。每个package
中的init
函数都是可选的,但package main
就必须包含一个main
函数。程序的初始化和执行都起始于main
包。如果main
包还导入了其它的包,那么就会在编译时将它们依次导入。有时一个包会被多个包同时导入,那么它只会被导入一次(例如很多包可能都会用到fmt
包,但它只会被导入一次,因为没有必要导入多次)。当一个包被导入时,如果该包还导入了其它的包,那么会先将其它包导入进来,然后再对这些包中的包级常量和变量进行初始化,接着执行init
函数(如果有的话),依次类推。等所有被导入的包都加载完毕了,就会开始对main
包中的包级常量和变量进行初始化,然后执行main
包中的init
函数(如果存在的话),最后执行main
函数。下图详细地解释了整个执行过程:
一句话总结执行过程: import –> const –> var –> init()
–> main()
Go的import还支持如下两种方式来加载自己写的模块:
- 相对路径 import “./model” //当前文件同一目录的model目录,但是不建议这种方式来import
- 绝对路径 import “shorturl/model” //加载gopath/src/shorturl/model模块
var x int
func init() {
x++
}
func main() {
init() //编译错误,你不需要在任何地方调用这两个函数
fmt.Println(x)
}
import 点操作
import(
. "fmt"
)
这个点操作的含义就是这个包导入之后在你调用这个包的函数时,你可以省略前缀的包名,也就是前面你调用的fmt.Println("hello world")可以省略的写成Println("hello world")
import 别名操作
别名操作顾名思义我们可以把包命名成另一个我们用起来容易记忆的名字
import(
f "fmt"
)
别名操作的话调用包函数时前缀变成了我们的前缀,即f.Println("hello world")
import _操作
当导入一个包时,该包下的文件里所有init()函数都会被执行,然而,有些时候我们并不需要把整个包都导入进来,仅仅是是希望它执行init()函数而已。这个时候就可以使用 import _ 引用该包。即使用【import _ 包路径】只是引用该包,仅仅是为了调用init()函数,所以无法通过包名来调用包中的其他函数。
package main
import (
_ "quickstart/routers"
"github.com/astaxie/beego"
)
从Go 1.13开始,下划线_
可以出现在整数、浮点数和虚部数字面量中,以用做分段符以增强可读性。 但是要注意,在一个数值字面表示中,一个下划线_
不能出现在此字面表示的首尾,并且其两侧的字符必须为(相应进制的)数字字符或者进制表示头
// 合法的使用下划线的例子
6_9 // == 69
0_33_77_22 // == 0337722
0x_Bad_Face // == 0xBadFace
0X_1F_FFP-16 // == 0X1FFFP-16
0b1011_0111 + 0xA_B.Fp2i
// 非法的使用下划线的例子
_69 // 下划线不能出现在首尾
69_ // 下划线不能出现在首尾
6__9 // 下划线不能相连
0_xBadFace // x不是一个合法的八进制数字
1_.5 // .不是一个合法的十进制数字
1._5 // .不是一个合法的十进制数字
空白标识符 _ 也被用于抛弃值,如值 5 在:_, b = 5, 7 中被抛弃。_ 实际上是一个只写变量,你不能得到它的值。这样做是因为 Go 语言中你必须使用所有被声明的变量,但有时你并不需要使用从一个函数得到的所有返回值。_匿名变量不占用命名空间,不会分配内存,所以匿名变量之间不存在重复声明