Go变量作用域
Go变量作用域由声明位置决定,层级清晰。
作用域层级
全局作用域
Go
// 包级别变量,全局可见
package main
var globalVar int = 100
func main() {
fmt.Println(globalVar) // 可访问
}
func other() {
fmt.Println(globalVar) // 可访问
}
局部作用域
Go
func main() {
// 函数级别变量
var localVar int = 10
fmt.Println(localVar) // 可访问
if true {
fmt.Println(localVar) // 可访问(内部块)
}
}
func other() {
fmt.Println(localVar) // 编译错误!不可访问
}
块作用域
Go
func main() {
if true {
// 块级别变量
var blockVar int = 5
fmt.Println(blockVar) // 可访问
}
fmt.Println(blockVar) // 编译错误!块外不可访问
}
作用域层级图
Go
┌─────────────────────────────────────┐
│ 全局作用域(包级别) │
│ var global │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ 局部作用域(函数级别) │
│ func main() { var local } │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ 块作用域(if/for等) │
│ if { var block } │
└─────────────────────────────────────┘
变量可见性规则
内部可访问外部
Go
var global = 100
func main() {
local := 10
fmt.Println(global) // ✓ 访问全局
fmt.Println(local) // ✓ 访问局部
if true {
fmt.Println(global) // ✓
fmt.Println(local) // ✓ 内部访问外部
}
}
外部不可访问内部
Go
func main() {
if true {
block := 5
}
fmt.Println(block) // ✗ 块外不可访问
}
func other() {
local := 10
}
func main() {
fmt.Println(local) // ✗ 其他函数不可访问
}
短变量声明作用域
if语句块
Go
if n := 10; n > 5 {
fmt.Println(n) // ✓ 可访问
}
fmt.Println(n) // ✗ 块外不可访问
for语句块
Go
for i := 0; i < 10; i++ {
fmt.Println(i) // ✓ 可访问
}
fmt.Println(i) // ✗ 循环外不可访问
switch语句块
Go
switch n := 10; n {
case 10:
fmt.Println(n) // ✓ 可访问
}
fmt.Println(n) // ✗ 块外不可访问
变量遮蔽(同名覆盖)
内部遮蔽外部
Go
var x = 100
func main() {
x := 10 // 遮蔽全局x
fmt.Println(x) // 10(局部x)
if true {
x := 5 // 遮蔽函数x
fmt.Println(x) // 5(块x)
}
fmt.Println(x) // 10(恢复函数x)
}
内部同名变量遮蔽外部变量,可能导致意外错误。
避免遮蔽
text
// 不推荐:同名遮蔽
var count = 0
func process() {
count := 1 // 遮蔽全局
}
// 推荐:使用不同名称
var globalCount = 0
func process() {
localCount := 1 // 名称区分
}
作用域对比表
| 作用域 | 声明位置 | 可见范围 |
|---|---|---|
| 全局 | 函数外 | 整个包 |
| 局部 | 函数内 | 函数内所有块 |
| 块 | if/for等内 | 仅该块 |
| 遮蔽 | 内部同名 | 覆盖外部 |
要点总结
- 作用域:全局→局部→块,层级分明
- 内部可访问外部变量
- 外部不可访问内部变量
- 短变量声明局限在其语句块
- 同名变量遮蔽:内部覆盖外部
- 避免遮蔽:使用不同名称
- 注意:=在块内创建新变量而非赋值外部
📝 发现内容有误?点击此处直接编辑