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 已离开作用域

小结:变量先声明后使用,块越小作用域越小。能用局部变量就别用全局变量——全局变量会加大耦合、难维护。

笔记加载中…