「译」Golang 中的 init 函数 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
darluc
V2EX    Go 编程语言

「译」Golang 中的 init 函数

  •  2
     
  •   darluc 2021-01-10 22:10:40 +08:00 2441 次点击
    这是一个创建于 1785 天前的主题,其中的信息可能已经有所发展或是发生改变。

    「阅读全文」

    标识符 main 无所不在。每个 Go 程序的执行都是从 main 包中一个拥有相同名字的函数开始的。当这个 main 函数返回时,整个程序也退出了执行。init 函数也扮演着特定的角色,本文会描述它们的特性并介绍它们的使用方法。

    init 函数是定义在包级别的,它被用于:

    • 初始化无法使用表达式初始化的变量
    • 检查和修复程序的状态
    • 注册
    • 执行一次性的运算
    • 以及其它

    除了下面要介绍一些区别,你可以将任何在一般函数中有效的代码放在其中。

    包的初始化

    要使用一个引入的包,首先它需要被初始化。这是由 Golang 的运行系统来完成的,由以下几步(顺序很重要)组成:

    1. 初始化引入的包(递归释义)
    2. 计算并初始化赋值包级别的变量
    3. 执行包内的 init 方法

    包的初始化过程只会被执行一次,即使它被多次引用

    顺序

    Go 语言的包可以包含许多文件。那么在这些包和文件中,变量的初始化和 init 函数的执行顺序是怎样的呢?首先,初始化依赖机制会起作用(详情可以查看“Go 中的初始化依赖”)。当依赖工作完成后,必须决定先初始化 a.go 文件中的变量还是 z.go 文件中的变量。这依赖于文件在编译器中出现的顺序。如果 z.go 先被提交给构建系统,那么它的变量就会先于 a.go 中的变量初始化。init 方法的调用也遵守相同的顺序。语言规格定义中建议总是采用相同的顺序,并且将包中的文件按单词拼写顺序传入:

    为了保证初始化行为可稳定复现,构建系统应该倾向于将同一个包中的多个文件按文件名的单词拼写顺序传递给编译器。

    不过对于移植性较差的程序来说也可以使用特别的顺序。我们用下面的例子看看这些是如何一起工作的:

    sandbox.go

    package main import "fmt" var _ int64 = s() func init() { fmt.Println("init in sandbox.go") } func s() int64 { fmt.Println("calling s() in sandbox.go") return 1 } func main() { fmt.Println("main") } 

    a.go

    package main import "fmt" var _ int64 = a() func init() { fmt.Println("init in a.go") } func a() int64 { fmt.Println("calling a() in a.go") return 2 } 

    z.go

    package main import "fmt" var _ int64 = z() func init() { fmt.Println("init in z.go") } func z() int64 { fmt.Println("calling z() in z.go") return 3 } 

    程序输出:

    calling a() in a.go calling s() in sandbox.go calling z() in z.go init in a.go init in sandbox.go init in z.go main 

    属性

    init 函数不接受任何参数,也没有返回值。于 main 相比,标识符 init 是没有被申明的,所以无法被引用:

    「阅读全文」

    3 条回复    2021-01-12 17:44:51 +08:00
    CEBBCAT
        1
    CEBBCAT  
       2021-01-10 23:45:08 +08:00 via Android
    我觉得标题中的译可以或者说应该用方括号,就是那种内部涂黑的,V2 好像会转化那种括号到这个: [,也不错
    iugo
        2
    iugo  
       2021-01-11 17:45:47 +08:00
    undertonememorie
        3
    undertonememorie  
       2021-01-12 17:44:51 +08:00
    单个文件多个 init 执行顺序是什么?同一 package 下,init 的执行顺序又是什么,
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3816 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 33ms UTC 00:59 PVG 08:59 LAX 16:59 JFK 19:59
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86