🌍 Go 变量作用域全解|全局·局部·块作用域一次吃透

2026-06-17 22 0

本篇基于 Go 1.25.1 版本,带你彻底理解变量作用域,搞懂全局、局部、块级范围,再也不踩变量遮蔽的坑✅


一、什么是变量作用域?

一句话:
变量能被访问、使用的有效代码范围
超出范围 → 报错“未定义”

Go 作用域分 3 类:

  1. 1. 全局作用域
  2. 2. 函数/局部作用域
  3. 3. 块作用域(if/for/switch 内部)

二、作用域分类对照表(直接收藏)

类型定义位置访问范围生命周期
全局变量函数外、包内整个包所有函数程序全程
局部变量函数内当前函数内部函数执行期间
块变量if/for/switch 内当前代码块内部块执行期间

三、逐类精讲 + 清晰示例

1. 全局作用域(包内全局)

函数外定义,整个包都能用
大写 → 包外可访问
小写 → 包内可访问

package main

// 全局变量
var globalMsg = "我是全局变量"

func main() {
    fmt.Println(globalMsg) // 可访问
}

2. 局部作用域(函数内)

函数内定义,只能在当前函数用

func test() {
    localNum := 100 // 局部变量
    fmt.Println(localNum)
}

func main() {
    // fmt.Println(localNum) → 报错!
}

3. 块作用域(if/for/switch 内部)

只在当前大括号{}内有效

if true {
    blockVal := "我在if块里"
    fmt.Println(blockVal) // 正常
}
// fmt.Println(blockVal) → 报错!

四、重点规则:同名变量遮蔽(Shadow)

内部变量会覆盖/遮蔽外部同名变量

var num = 10 // 全局

func main() {
    num := 20 // 局部遮蔽全局
    fmt.Println(num) // 20
}

五、完整可运行 Demo(全覆盖、可直接跑)

main.go 零语法错误,演示所有作用域👇

package main

import "fmt"

// ==================== 1. 全局变量(包内所有函数可用) ====================
var globalName = "Go全局变量"
var globalAge = 18

func main() {
    fmt.Println("=== 1. 访问全局变量 ===")
    fmt.Println("全局名称:", globalName)

    // ==================== 2. 局部变量(仅 main 函数内可用) ====================
    localMsg := "我是 main 函数局部变量"
    fmt.Println("\n=== 2. 局部变量 ===")
    fmt.Println(localMsg)

    // ==================== 3. 块作用域(if 内部) ====================
    fmt.Println("\n=== 3. if 块作用域 ===")
    if true {
        blockMsg := "我在 if 代码块里"
        fmt.Println(blockMsg)
    }
    // fmt.Println(blockMsg) // 报错:超出作用域

    // ==================== 4. 变量遮蔽(重点) ====================
    fmt.Println("\n=== 4. 变量遮蔽 ===")
    globalAge := 99 // 局部变量遮蔽全局
    fmt.Println("局部 age:", globalAge)
    fmt.Println("全局 age:", globalAge) // 内部优先

    // 调用函数测试全局
    testFunc()
}

// testFunc 测试全局变量
func testFunc() {
    fmt.Println("\n=== testFunc 访问全局 ===")
    fmt.Println("全局名称:", globalName)
    // fmt.Println(localMsg) // 报错!
}

运行命令

go run main.go

运行结果

=== 1. 访问全局变量 ===
全局名称: Go全局变量

=== 2. 局部变量 ===
我是 main 函数局部变量

=== 3. if 块作用域 ===
我在 if 代码块里

=== 4. 变量遮蔽 ===
局部 age: 99
全局 age: 99

=== testFunc 访问全局 ===
全局名称: Go全局变量

六、作用域核心规则(必背)

  1. 1. 外层变量 → 内层可访问
  2. 2. 内层变量 → 外层不可访问
  3. 3. 同名变量:内层覆盖外层(遮蔽)
  4. 4. 大括号{}就是一个作用域
  5. 5. 全局变量生命周期 = 程序全程

七、新手避坑指南

  1. 1. ❌ 同名变量遮蔽导致逻辑错误
  2. 2. ❌ 超出块范围访问变量
  3. 3. ❌ 函数内访问另一个函数的局部变量
  4. 4. ✅ 尽量少用全局变量(不易维护)
  5. 5. ✅ 变量尽量定义在离使用最近的地方

📌 总结

  1. 1. 全局变量:函数外,整个包可用
  2. 2. 局部变量:函数内,仅当前函数
  3. 3. 块变量if/for内,仅当前{}
  4. 4. 同名遮蔽:内部覆盖外部
  5. 5. 作用域越小越安全、越规范

一篇搞定 Go 变量作用域,写代码再也不踩范围坑✨

 

相关文章

🚨 Go 变量遮蔽|新手最容易踩的隐形坑!一篇避坑
🔍 Go 空白标识符 _ 全攻略|忽略值·导包神器用法大全
🚀 Go main 函数详解|程序入口核心玩法全掌握
🚀 Go init 函数详解|程序初始化的秘密入口
🔑 Go 可见性规则|大小写决定一切!新手必懂
🔍 Go 类型断言基础|空接口类型判断一学就会!

发布评论