首先来看两个golang的示例程序:
示例1:
package main
import “fmt”
var (
a int = b + 1
b int = 1
)
func main() {
fmt.Println(a)
fmt.Println(b)
}
示例2:
package main
import "fmt"
func main() {
var (
a int = b + 1
b int = 1
)
fmt.Println(a)
fmt.Println(b)
}
大家想一下,这两个程序的输出是否一样呢?当然不一样啦,要是一样的话,我写这两段程序就没意义了。
示例1 输出:
1
2
示例2 输出:
# command-line-arguments
./interest.go:7: undefined: b
输出不同的原因:不同作用域类型的变量初始化顺序不同。
示例2中的变量a,b是函数作用域内的局部变量,初始化顺序:从左到右、从上到下。
func f() int { fmt.Println("f"); return 1 }
func g() int { fmt.Println("g"); return 2 }
func h() int { fmt.Println("h"); return 3 }
func main() {
var (
a int = f()
b int = g()
c int = h()
)
fmt.Println(a, b, c)
}
输出:
f
g
h
1 2 3
但是对于示例1中package级别的变量,初始化顺序与初始化依赖有关。
package main
import "fmt"
var (
a = c — 2
b = 2
c = f()
)
func f() int {
fmt.Printf("inside f and b = %d\n", b)
return b + 1
}
func main() {
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
}
上述代码的初始化顺序:
- b在第一个初始化周期(initialization cycle)被初始化,因为变量b不依赖任何其他变量;
- c在第二个初始化周期被初始化,因为a的初始化依赖c;
- a在第三个初始化周期被初始化;
输出:
inside f and b = 2
1
2
3
在每一个初始化周期,运行时(runtime)会挑选一个没有任何依赖的变量初始化,该过程一直持续到所有的变量均被初始化或者出现依赖嵌套的情形:
package main
import "fmt"
var (
a = b
b = c
c = f()
)
func f() int {
return a
}
func main() {
fmt.Println(a, b, c)
}
编译器会提示错误:“initialization loop”
同一个package下多个文件的变量初始化依赖也遵循相同的规则:
tools.go
package main
import "fmt"
var (
a = c — 2
b = 2
)
func main() {
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
}
utils.go
package main
var c = f()
func f() int {
return b + 1
}
输出:
1
2
3
想了解更多golang编程相关知识,请扫描上面二维码关注微信公众号 bloomingTony