变量是程序存储数据的基本单位,常量则用于表示固定不变的值。Go语言在变量和常量的设计上既保持了静态类型的安全性,又通过类型推断和简洁的语法提供了动态语言的灵活性。本章将详细讲解Go中变量与常量的声明、初始化、作用域以及特殊用法。
:= 是函数内部最常用的方式;常量在编译时求值,只能是基本类型。
Go是静态强类型语言,但支持类型推断,使得声明变量有多种形式。
var name typepackage main
import "fmt"
func main() {
var name string // 声明一个 string 变量,初始值为零值 ""
var age int // 零值为 0
var isActive bool // 零值为 false
name = "Alice"
age = 30
isActive = true
fmt.Println(name, age, isActive)
}
var city string = "Beijing"
var score int = 95
var flag bool = true
编译器会根据初始值自动推断变量类型。
var name = "Bob" // 推断为 string
var age = 25 // 推断为 int
var pi = 3.14159 // 推断为 float64
在函数内部,可以使用 := 代替 var 声明并初始化,类型由编译器推断。
func main() {
message := "Hello, Go" // 等价于 var message string = "Hello, Go"
count := 10
ratio := 0.618
// 注意:短变量声明不能用于全局变量(包级作用域)
}
count := 5; count := 10 会报错(重复声明),但可以使用赋值 count = 10。
// 使用 var
var x, y int = 10, 20
var a, b = "foo", true
// 短变量声明
c, d := 3.14, "pi"
// 批量声明(适合包级变量)
var (
username string = "admin"
port int = 8080
enabled bool = true
)
在Go中,变量声明后如果不显式初始化,会被自动赋予其类型的零值(默认值)。这一特性保证了变量始终处于可用状态,避免了未初始化的随机值问题。
| 类型 | 零值 |
|---|---|
| 数值类型(int, float, complex) | 0 |
| 布尔类型 bool | false |
| 字符串 string | ""(空字符串) |
| 指针、切片、map、通道、函数、接口 | nil |
| 数组、结构体 | 内部每个元素/字段的零值 |
var i int // 0
var f float64 // 0.0
var b bool // false
var s string // ""
var p *int // nil
var arr [3]int // [0, 0, 0]
var slice []int // nil (但 nil 切片可以 append)
var m map[string]int // nil (不能直接赋值,需要用 make 初始化)
userName)。Go中首字母大写表示公开(public),小写表示私有(private)。package main
var globalVar = "I am global" // 包级私有变量
var ExportedVar = "I am exported" // 可被其他包访问
func main() {
localVar := "I am local"
{
innerVar := "inside block"
fmt.Println(innerVar)
}
// fmt.Println(innerVar) // 编译错误:innerVar 不可见
}
常量使用 const 关键字声明,其值在编译时确定,程序运行时不可改变。常量可以是无类型常量(更灵活)或有类型常量。
const Pi = 3.14159 // 无类型浮点常量
const StatusOK = 200 // 无类型整数常量
const (
Monday = "Monday"
Tuesday = "Tuesday"
)
const (
a = 1
b // 省略值表示与上一行相同,即 b = 1
)
const c int = 100 // 有类型常量
iota 是Go内置的常量生成器,在 const 块中每次出现时自增1,初始为0。常用于生成枚举值。
const (
Sunday = iota // 0
Monday // 1
Tuesday // 2
Wednesday // 3
Thursday // 4
Friday // 5
Saturday // 6
)
const (
_ = iota // 0,跳过
KB = 1 << (10 * iota) // 1 << 10 = 1024
MB = 1 << (10 * iota) // 1 << 20 = 1048576
GB = 1 << (10 * iota) // 1 << 30
)
// 自定义表达式
const (
A = iota * 2 // 0
B // 2
C // 4
)
Go中变量一旦声明为某种类型,不能隐式转换为其他类型,必须显式转换。
var i int = 42
var f float64 = float64(i) // 显式转换
var u uint = uint(f)
// 不同类型变量不能直接赋值或比较
// var x int = 10
// var y float64 = x // 编译错误
// 常量可以自动转换(因为常量是无类型的)
const ci = 10
var f2 float64 = ci // 允许,ci 作为无类型常量被转换为 float64
package main
import "fmt"
// 包级常量
const (
AppName = "GoCalculator"
Version = "1.0.0"
)
// 包级变量(零值初始化)
var result float64
func main() {
// 局部变量
a := 10.5
b := 20.3
// 使用常量
fmt.Printf("%s v%s\n", AppName, Version)
// 运算
result = a + b
fmt.Printf("%g + %g = %g\n", a, b, result)
// 类型转换示例
var count int = 5
avg := result / float64(count) // 必须显式转换
fmt.Printf("Average: %.2f\n", avg)
// iota 枚举
const (
StatusPending = iota
StatusRunning
StatusCompleted
StatusFailed
)
fmt.Println("Status Pending:", StatusPending) // 0
fmt.Println("Status Running:", StatusRunning) // 1
}
运行输出: