Go 变量作用域
作用域决定变量在哪里可见、可用。Go 的规则很简单:变量属于它所在的花括号块 {},离开该块就失效。(说明:文中的片段代码需放进完整程序里运行)
局部变量
函数内、代码块内声明的变量都是局部变量,离开所在块就不能再用:
package main
import "fmt"
func main() {
if x := 10; x > 0 { // if 初始化写法:x 只属于这个 if 块
y := x * 2 // y 也是块内局部变量
fmt.Println(x, y) // 10 20
}
// 到这里 x、y 都已失效,再引用会报 undefined
}
// 输出: 10 20
if x := 10; x > 0 是 Go 特有的 if 初始化写法,x 的作用域就是整个 if 语句块。
全局变量
在函数外、package 级声明的变量是全局变量(包级变量),同包的所有函数都能访问、修改:
package main
import "fmt"
var version = "v1.0" // 全局变量
func show() { fmt.Println("版本:", version) }
func main() {
version = "v2.0" // 函数里直接改全局变量
show()
}
// 输出: 版本: v2.0
全局变量在程序启动时初始化,多个文件同属一个包时共享它们。注意函数内用 := 声明同名变量会遮蔽全局变量:
var msg = "全局"
func main() {
msg := "局部" // 遮蔽包级变量
fmt.Println(msg) // 局部优先
}
// 输出: 局部
形参的作用域
形参(函数参数)相当于函数的局部变量,作用域是整个函数体,调用结束即销毁:
func square(n int) int {
n = n * n // 修改形参
return n
}
// a := 4; square(a) → 16;a 仍是 4(普通参数按值传递)
作用域示例:嵌套块
内层块能访问外层变量,外层不能访问内层;内层声明同名变量会遮蔽外层:
a := 1
{
a := 2 // 遮蔽外层 a
b := 3
fmt.Println(a, b) // 2 3
}
fmt.Println(a) // 1:外层 a 没被影响
// fmt.Println(b) // 错误:b 已离开作用域
小结:变量先声明后使用,块越小作用域越小。能用局部变量就别用全局变量——全局变量会加大耦合、难维护。