变量和常量是编程语言的基础概念。本章将详细介绍 Go 语言中变量和常量的声明、使用和注意事项。
变量是程序中存储数据的"容器"。你可以把变量想象成一个盒子,盒子有名字(变量名),里面可以放东西(值)。
┌─────────────┐
│ age = 25 │ ← 变量名:age,值:25
└─────────────┘
Go 是静态类型语言,变量必须有明确的类型。
使用 var 关键字声明变量:
var name string
var age int
var salary float64
var isActive bool
语法格式:
var 变量名 类型
声明的同时赋初值:
var name string = "张三"
var age int = 25
var salary float64 = 10000.50
var isActive bool = true
如果声明时赋值,可以省略类型,Go 会自动推断:
var name = "张三"
var age = 25
var salary = 10000.50
var isActive = true
在函数内部,可以使用 := 短变量声明:
name := "张三"
age := 25
salary := 10000.50
isActive := true
注意:短变量声明只能在函数内部使用。
一次声明多个变量:
var (
name string
age int
salary float64
isActive bool
)
批量声明并赋值:
var (
name string = "张三"
age int = 25
salary float64 = 10000.50
isActive bool = true
)
package main
import "fmt"
func main() {
var name string
name = "张三"
fmt.Println(name)
var age int = 25
fmt.Println(age)
city := "北京"
fmt.Println(city)
x, y := 10, 20
fmt.Println(x, y)
}
输出:
张三
25
北京
10 20
Go 语言中,声明但未赋值的变量会自动初始化为"零值":
| 类型 | 零值 |
|---|---|
| int, float | 0 |
| string | ""(空字符串) |
| bool | false |
| 指针、切片、map、chan、函数 | nil |
示例:
package main
import "fmt"
func main() {
var i int
var f float64
var s string
var b bool
fmt.Printf("int: %d\n", i)
fmt.Printf("float: %f\n", f)
fmt.Printf("string: %q\n", s)
fmt.Printf("bool: %t\n", b)
}
输出:
int: 0
float: 0.000000
string: ""
bool: false
| 规则 | 正确示例 | 错误示例 |
|---|---|---|
| 以字母或下划线开头 | name, _name | 1name |
| 只能包含字母、数字、下划线 | user_name | user-name |
| 区分大小写 | Name 和 name 是不同变量 | - |
| 不能使用关键字 | - | var, func, if |
| 风格 | 示例 | 说明 |
|---|---|---|
| 驼峰命名(推荐) | userName, maxAge | Go 推荐风格 |
| 帕斯卡命名 | UserName, MaxAge | 公开的变量/函数 |
| 下划线命名 | user_name, max_age | 不推荐 |
a, b, c 这种无意义名称is, has, can 开头,如 isActive, hasPermissioni, j 用于循环常量是程序运行期间不会改变的值。使用 const 关键字声明。
const Pi = 3.14159
const AppName = "MyApp"
const MaxSize = 100
const (
StatusOK = 200
StatusNotFound = 404
StatusError = 500
)
package main
import "fmt"
func main() {
const Pi = 3.14159
fmt.Println(Pi)
Pi = 3.14
}
iota 是 Go 语言的常量计数器,只能在常量声明中使用。
const (
a = iota
b = iota
c = iota
)
fmt.Println(a, b, c)
输出:
0 1 2
在 const 块中,如果某一行没有写表达式,会复用上一行的表达式:
const (
a = iota
b
c
)
fmt.Println(a, b, c)
输出:
0 1 2
const (
Sunday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)
fmt.Println(Sunday, Monday, Saturday)
输出:
0 1 6
const (
Read = 1 << iota
Write
Execute
)
fmt.Println(Read, Write, Execute)
输出:
1 2 4
解释:
| 常量 | 值 | 二进制 |
|---|---|---|
| Read | 1 | 001 |
| Write | 2 | 010 |
| Execute | 4 | 100 |
可以组合使用:
permission := Read | Write
fmt.Println(permission)
输出:
3
使用 _ 跳过某个值:
const (
a = iota
_
b
_
c
)
fmt.Println(a, b, c)
输出:
0 2 4
| 对比项 | 变量 | 常量 |
|---|---|---|
| 关键字 | var | const |
| 值是否可变 | 可变 | 不可变 |
| 类型 | 必须有类型 | 可以无类型 |
| 赋值时机 | 运行时 | 编译时 |
| 内存分配 | 会分配内存 | 不会分配内存 |
变量的作用域是指变量可以被访问的范围。
在函数内部声明的变量,只能在函数内使用:
func main() {
name := "张三"
fmt.Println(name)
}
func other() {
fmt.Println(name)
}
在函数外部声明的变量,可以在整个包内使用:
package main
import "fmt"
var globalVar = "我是全局变量"
func main() {
fmt.Println(globalVar)
}
func other() {
fmt.Println(globalVar)
}
在代码块(如 if、for)内声明的变量,只能在块内使用:
func main() {
if true {
x := 10
fmt.Println(x)
}
fmt.Println(x)
}
func main() {
name := "张三"
age := 25
fmt.Println(name)
}
错误信息:
age declared but not used
解决方法:使用变量或删除未使用的变量。
package main
name := "张三"
func main() {
fmt.Println(name)
}
错误信息:
syntax error: non-declaration statement outside function body
解决方法:使用 var 声明:
var name = "张三"
func main() {
name := "张三"
name := "李四"
}
错误信息:
no new variables on left side of :=
解决方法:使用 = 赋值:
name := "张三"
name = "李四"
本章学习了 Go 语言的变量和常量:
| 知识点 | 说明 |
|---|---|
var 声明 | 标准变量声明方式 |
:= 短声明 | 函数内的简洁声明方式 |
| 零值 | 未赋值变量的默认值 |
const | 常量声明 |
iota | 常量计数器,用于枚举 |