2025-12-28 14:53:22 +08:00
|
|
|
|
# 变量作用域
|
|
|
|
|
|
|
2025-12-28 15:53:05 +08:00
|
|
|
|
作用域: 这个变量在哪个范围内可以被访问到
|
|
|
|
|
|
|
|
|
|
|
|
+ 基础作用域: 块作用域, {}, 在块作用域下的变量都是局部变量
|
|
|
|
|
|
|
|
|
|
|
|
## 局部变量
|
|
|
|
|
|
|
|
|
|
|
|
### 父作用域 不能访问子作用域的变量
|
|
|
|
|
|
|
|
|
|
|
|
```go
|
|
|
|
|
|
{
|
|
|
|
|
|
{
|
|
|
|
|
|
var a string
|
|
|
|
|
|
a = "local var"
|
|
|
|
|
|
fmt.Println(a)
|
|
|
|
|
|
}
|
|
|
|
|
|
// fmt.Println(a)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 子作用域可以访问父作用域的变量
|
|
|
|
|
|
|
|
|
|
|
|
```go
|
|
|
|
|
|
{
|
|
|
|
|
|
var a string
|
|
|
|
|
|
a = "parent scope"
|
|
|
|
|
|
{
|
|
|
|
|
|
fmt.Println(a)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 变量值覆盖
|
|
|
|
|
|
|
|
|
|
|
|
子作用域的优先级是高于父作用域的优先级的, 因此子作用域可以覆盖父作用域的变量的值, 但是同一个变量不能声明2次
|
|
|
|
|
|
|
|
|
|
|
|
```go
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
|
|
import "fmt"
|
|
|
|
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
|
|
var a = "parent"
|
|
|
|
|
|
fmt.Println("outer:", a) // parent
|
|
|
|
|
|
{
|
|
|
|
|
|
a := "child" // 子作用域声明了同名新变量(遮蔽外层 a)
|
|
|
|
|
|
fmt.Println("inner:", a) // child
|
|
|
|
|
|
}
|
|
|
|
|
|
fmt.Println("outer again:", a) // 仍为 parent
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 全局变量
|
|
|
|
|
|
|
|
|
|
|
|
在函数体外声明的变量称之为全局变量,全局变量可以在整个包甚至外部包(被导出后)使用, 全局变量相当于所有函数的父级变量, 所有函数都能访问
|
|
|
|
|
|
|
|
|
|
|
|
```go
|
|
|
|
|
|
var (
|
|
|
|
|
|
a = "global parent scope var"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
|
|
fmt.Println(a)
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 导出与不可导出(可见性)
|
|
|
|
|
|
|
|
|
|
|
|
约定:标识符以大写字母开头表示可导出(可被其他包访问),以小写字母开头表示仅包内可见。
|
|
|
|
|
|
|
|
|
|
|
|
```go
|
|
|
|
|
|
// 包内文件 a.go
|
|
|
|
|
|
package demo
|
|
|
|
|
|
|
|
|
|
|
|
var Exported = "可导出"
|
|
|
|
|
|
var internal = "包内可见"
|
|
|
|
|
|
|
|
|
|
|
|
// 其他包:import demo 后只能访问 demo.Exported
|
|
|
|
|
|
```
|