变量与常量 #

一、变量 #

1.1 变量声明 #

使用var关键字声明变量:

go
var name string
var age int
var isActive bool

声明时初始化:

go
var name string = "Go"
var age int = 15

类型推断:

go
var name = "Go"      // 自动推断为string
var age = 15         // 自动推断为int
var isActive = true  // 自动推断为bool

1.2 批量声明 #

go
var (
    name     string
    age      int
    isActive bool
)

批量声明并初始化:

go
var (
    name     string = "Go"
    age      int    = 15
    isActive bool   = true
)

1.3 短变量声明 #

在函数内部,可以使用:=短声明:

go
name := "Go"
age := 15
isActive := true

注意:

  • 只能在函数内部使用
  • 必须声明新变量
  • 自动推断类型
go
func main() {
    name := "Go"      // 正确
    var age = 15      // 正确
    
    name := "Golang"  // 错误:name已声明
    name = "Golang"   // 正确:赋值
}

1.4 多变量声明 #

go
var x, y int           // 声明多个同类型变量
var a, b = 1, "hello"  // 声明多个不同类型变量

x, y := 1, 2           // 短声明多个变量

交换变量值:

go
a, b := 1, 2
a, b = b, a  // 交换

1.5 零值 #

未初始化的变量会被赋予零值:

类型 零值
int, float 0
string “”(空字符串)
bool false
pointer, slice, map, chan, func nil
struct 各字段零值
go
var i int       // 0
var s string    // ""
var b bool      // false
var p *int      // nil

二、常量 #

2.1 常量声明 #

使用const关键字:

go
const Pi = 3.14159
const Language = "Go"

显式指定类型:

go
const Pi float64 = 3.14159
const MaxSize int = 100

2.2 批量声明 #

go
const (
    Pi      = 3.14159
    E       = 2.71828
    Language = "Go"
)

2.3 常量特点 #

  • 编译时确定值
  • 必须是基本类型
  • 不能修改
go
const x = 10
x = 20  // 错误:不能修改常量

2.4 无类型常量 #

常量可以没有明确类型:

go
const x = 10        // 无类型常量
var i int = x       // 作为int使用
var f float64 = x   // 作为float64使用

三、iota枚举 #

3.1 基本用法 #

iota是常量计数器,从0开始:

go
const (
    Sunday = iota    // 0
    Monday           // 1
    Tuesday          // 2
    Wednesday        // 3
    Thursday         // 4
    Friday           // 5
    Saturday         // 6
)

3.2 跳过值 #

使用_跳过:

go
const (
    _ = iota        // 0,跳过
    KB = 1 << (10 * iota)  // 1 << 10 = 1024
    MB                     // 1 << 20
    GB                     // 1 << 30
    TB                     // 1 << 40
)

3.3 自定义值 #

go
const (
    a = iota    // 0
    b = 100     // 100
    c = iota    // 2
    d           // 3
)

3.4 位运算示例 #

go
const (
    Read = 1 << iota    // 1
    Write               // 2
    Execute             // 4
)

func main() {
    perm := Read | Write  // 3
    fmt.Println(perm&Read != 0)   // true
    fmt.Println(perm&Execute != 0) // false
}

3.5 复杂表达式 #

go
const (
    _  = iota
    KB = 1 << (10 * iota)
    MB
    GB
    TB
    PB
    EB
    ZB
    YB
)

四、作用域 #

4.1 局部变量 #

在函数内部声明的变量:

go
func main() {
    x := 10      // 局部变量
    var y = 20   // 局部变量
}

4.2 全局变量 #

在函数外部声明的变量:

go
var globalVar = 100

func main() {
    fmt.Println(globalVar)
}

4.3 块作用域 #

go
func main() {
    x := 10
    
    if true {
        x := 20     // 新变量,遮蔽外层x
        fmt.Println(x)  // 20
    }
    
    fmt.Println(x)  // 10
}

4.4 作用域规则 #

  • 内层可以访问外层变量
  • 内层可以声明同名变量(遮蔽)
  • 不同包的变量通过首字母大小写控制访问

五、最佳实践 #

5.1 命名建议 #

go
// 好
userName := "Tom"
maxRetryCount := 3
isAuthenticated := false

// 不好
n := "Tom"          // 太短
MAXRETRY := 3       // 全大写像常量

5.2 声明位置 #

go
// 好:在使用处声明
func process() {
    data := loadData()
    result := transform(data)
    fmt.Println(result)
}

// 不好:提前声明
func process() {
    var data []int
    var result []int
    data = loadData()
    result = transform(data)
    fmt.Println(result)
}

5.3 常量组织 #

go
const (
    StatusOK = 200
    StatusNotFound = 404
    StatusError = 500
)

const (
    DefaultTimeout = 30 * time.Second
    MaxRetryCount = 3
)

5.4 避免遮蔽 #

go
// 不好
func main() {
    x := 10
    if true {
        x := 20  // 遮蔽
        fmt.Println(x)
    }
}

// 好
func main() {
    x := 10
    if true {
        y := 20  // 使用不同名称
        fmt.Println(y)
    }
}

六、常见错误 #

6.1 未使用的变量 #

go
func main() {
    x := 10  // 错误:x declared but not used
}

解决:使用或删除变量

6.2 短声明在函数外 #

go
x := 10  // 错误:non-declaration statement outside function body

func main() {
    fmt.Println(x)
}

解决:使用var

go
var x = 10

func main() {
    fmt.Println(x)
}

6.3 类型不匹配 #

go
var x int = "hello"  // 错误:cannot use "hello" as int

解决:使用正确类型

七、总结 #

变量与常量要点:

特性 变量 常量
关键字 var, := const
可修改
类型推断 支持 支持
零值

关键点:

  1. 变量声明var:=
  2. 常量声明const
  3. 枚举:使用iota
  4. 零值:未初始化变量有默认值
  5. 作用域:注意变量遮蔽

准备好学习基本数据类型了吗?让我们进入下一章!

最后更新:2026-03-26