这里煮包总结的很系统,不懂的后面记得回来看。
一、基本变量声明
1. 标准声明方式
go
// 单个变量声明
var name string
var age int
var isStudent bool
// 多个同类型变量
var x, y int
// 多个不同类型变量
var (
firstName string
lastName string
score float64
enrolled bool
)
2. 声明并初始化
go
// 声明时初始化
var name string = "Alice"
var age int = 25
// 类型推断(编译器自动推断类型)
var name = "Bob" // 推断为 string
var age = 30 // 推断为 int
var salary = 50000.0 // 推断为 float64
// 多个变量同时初始化
var a, b, c = 1, 2.5, "hello"
3. 短变量声明(最常用)
go
// 只能在函数内部使用
func main() {
name := "Charlie" // 声明并初始化
age := 35 // int
height := 1.75 // float64
isEmployed := true // bool
// 多个变量
x, y, z := 10, 20, "world"
// 交换变量值
a, b := 1, 2
a, b = b, a // a=2, b=1
}
二、零值(Zero Values)
Go 中声明但未初始化的变量会自动赋零值:
go
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 m map[string]int // nil
var slice []int // nil
三、匿名变量(Blank Identifier)
1. 忽略函数返回值
go
func getUserInfo() (string, int, error) {
return "Alice", 30, nil
}
func main() {
// 只关心姓名,忽略年龄和错误
name, _, _ := getUserInfo()
fmt.Println(name) // Alice
// 只关心错误
_, _, err := getUserInfo()
if err != nil {
// 处理错误
}
}
2. 在循环中忽略索引或值
go
numbers := []int{1, 2, 3, 4, 5}
// 只关心值,不关心索引
for _, value := range numbers {
fmt.Println(value)
}
// 只关心索引,不关心值
for index, _ := range numbers {
fmt.Println(index)
}
3. 忽略导入包的副作用
go
import (
_ "database/sql" // 只执行包的init函数
"fmt"
_ "github.com/lib/pq" // PostgreSQL驱动注册
)
四、特殊变量用法
1. 常量声明
go
const Pi = 3.14159
const MaxSize = 1024
// 多个常量
const (
StatusOK = 200
StatusCreated = 201
Prefix = "GO_"
)
// iota 枚举
const (
Sunday = iota // 0
Monday // 1
Tuesday // 2
Wednesday // 3
)
// iota 表达式
const (
KB = 1 << (10 * iota) // 1 << 0 = 1
MB // 1 << 10 = 1024
GB // 1 << 20 = 1048576
)
2. 变量作用域
go
package main
var globalVar = "I'm global" // 包级别变量
func main() {
localVar := "I'm local" // 函数级别变量
{
blockVar := "I'm in block" // 块级别变量
fmt.Println(blockVar)
}
// fmt.Println(blockVar) // 错误:blockVar未定义
}
3. 指针变量
go
func main() {
x := 10
var ptr *int = &x // ptr指向x的地址
fmt.Println(x) // 10
fmt.Println(*ptr) // 10(解引用)
*ptr = 20 // 通过指针修改变量值
fmt.Println(x) // 20
}
4. 类型转换变量
go
func main() {
var i int = 42
var f float64 = float64(i) // 显式类型转换
var u uint = uint(f)
// 简短写法
f2 := float64(i)
u2 := uint(f2)
}
五、复合类型变量
1. 数组和切片
go
// 数组(固定长度)
var arr1 [3]int = [3]int{1, 2, 3}
arr2 := [...]int{1, 2, 3, 4} // 编译器计算长度
// 切片(动态数组)
var slice1 []int = []int{1, 2, 3}
slice2 := make([]int, 3, 5) // 长度3,容量5
slice3 := []string{"a", "b", "c"}
2. Map
go
// 声明并初始化
var m1 map[string]int = map[string]int{
"apple": 1,
"banana": 2,
}
// 短声明
m2 := map[string]float64{
"pi": 3.14159,
"e": 2.71828,
}
// 使用make
m3 := make(map[int]string)
m3[1] = "one"
3. 结构体
go
type Person struct {
Name string
Age int
}
func main() {
// 各种初始化方式
var p1 Person
p1.Name = "Alice"
p2 := Person{"Bob", 30} // 必须按顺序
p3 := Person{
Name: "Charlie",
Age: 25, // 注意末尾逗号
}
// 匿名结构体
p4 := struct {
Name string
Age int
}{
Name: "David",
Age: 28,
}
}
总结要点
- 短声明 (:=) 最常用,但只能在函数内使用
- var 声明 用于包级别变量或需要零值的变量
- 匿名变量 (_) 用于忽略不需要的返回值
- Go 有自动零值初始化,不会出现未初始化错误
- 变量作用域严格遵循块作用域规则
- 类型转换必须显式进行
- 复合类型(map、slice)需要初始化后才能使用
掌握这些变量用法是学习 Go 语言的基础,建议多练习不同的声明和初始化方式,理解它们各自适用的场景。