数据结构
数组
数组是固定长度的相同类型元素的序列。
声明和初始化
go
// 声明数组
var arr [5]int
// 初始化
var arr1 [5]int = [5]int{1, 2, 3, 4, 5}
arr2 := [5]int{1, 2, 3, 4, 5}
// 让编译器推断长度
arr3 := [...]int{1, 2, 3, 4, 5}
// 指定索引初始化
arr4 := [5]int{1: 10, 3: 30}数组操作
go
arr := [5]int{1, 2, 3, 4, 5}
// 访问元素
first := arr[0]
last := arr[4]
// 修改元素
arr[0] = 10
// 数组长度
length := len(arr)
// 遍历数组
for i := 0; i < len(arr); i++ {
fmt.Println(arr[i])
}
for index, value := range arr {
fmt.Printf("索引: %d, 值: %d\n", index, value)
}切片(Slice)
切片是动态数组,是 Go 语言中最重要的数据结构之一。
创建切片
go
// 方式 1: 从数组创建
arr := [5]int{1, 2, 3, 4, 5}
slice := arr[1:4] // [2, 3, 4]
// 方式 2: 使用字面量
slice1 := []int{1, 2, 3, 4, 5}
// 方式 3: 使用 make
slice2 := make([]int, 5) // 长度 5,容量 5
slice3 := make([]int, 5, 10) // 长度 5,容量 10
// 方式 4: 空切片
var slice4 []int
slice5 := []int{}切片操作
go
slice := []int{1, 2, 3, 4, 5}
// 访问元素
first := slice[0]
// 修改元素
slice[0] = 10
// 长度和容量
length := len(slice)
capacity := cap(slice)
// 追加元素
slice = append(slice, 6)
slice = append(slice, 7, 8, 9)
// 追加另一个切片
slice2 := []int{10, 11}
slice = append(slice, slice2...)
// 切片操作
slice3 := slice[1:3] // [2, 3]
slice4 := slice[:3] // [1, 2, 3]
slice5 := slice[2:] // [3, 4, 5]切片底层原理
切片包含三个部分:
- 指针:指向底层数组
- 长度:切片中元素的数量
- 容量:从切片开始位置到底层数组末尾的元素数量
go
slice := make([]int, 3, 5)
// 长度: 3, 容量: 5
// 底层数组: [0, 0, 0, _, _]Map(映射)
Map 是键值对的集合。
创建和初始化
go
// 方式 1: 使用 make
m := make(map[string]int)
// 方式 2: 字面量
m1 := map[string]int{
"apple": 5,
"banana": 3,
}
// 方式 3: 空 map
var m2 map[string]int
// 注意: 空 map 不能直接使用,需要初始化Map 操作
go
m := make(map[string]int)
// 添加/修改元素
m["apple"] = 5
m["banana"] = 3
// 获取元素
value := m["apple"]
// 检查键是否存在
value, exists := m["apple"]
if exists {
fmt.Println("存在")
}
// 删除元素
delete(m, "apple")
// 遍历 map
for key, value := range m {
fmt.Printf("键: %s, 值: %d\n", key, value)
}
// 只遍历键
for key := range m {
fmt.Println(key)
}
// 只遍历值
for _, value := range m {
fmt.Println(value)
}结构体(Struct)
结构体是自定义类型的集合。
定义结构体
go
type Person struct {
Name string
Age int
City string
}
// 嵌套结构体
type Address struct {
Street string
City string
}
type Person struct {
Name string
Age int
Address Address
}创建和使用
go
// 方式 1: 字面量
p1 := Person{
Name: "Alice",
Age: 30,
City: "Beijing",
}
// 方式 2: 按顺序
p2 := Person{"Bob", 25, "Shanghai"}
// 方式 3: 部分初始化
p3 := Person{Name: "Charlie"}
// 访问字段
fmt.Println(p1.Name)
p1.Age = 31
// 指针
p4 := &Person{Name: "David", Age: 28}
fmt.Println((*p4).Name) // 方式 1
fmt.Println(p4.Name) // 方式 2 (Go 自动解引用)结构体方法
go
type Rectangle struct {
Width float64
Height float64
}
// 值接收者方法
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
// 指针接收者方法
func (r *Rectangle) Scale(factor float64) {
r.Width *= factor
r.Height *= factor
}指针
指针存储变量的内存地址。
指针操作
go
x := 42
p := &x // 获取 x 的地址
fmt.Println(*p) // 通过指针访问值
*p = 21 // 通过指针修改值
// 指针的零值是 nil
var p *int
if p == nil {
fmt.Println("指针为空")
}指针和结构体
go
type Person struct {
Name string
Age int
}
p := &Person{Name: "Alice", Age: 30}
// Go 自动处理解引用
fmt.Println(p.Name) // 不需要 (*p).Name
p.Age = 31示例程序
go
package main
import "fmt"
func main() {
// 数组
arr := [5]int{1, 2, 3, 4, 5}
fmt.Println("数组:", arr)
// 切片
slice := []int{1, 2, 3}
slice = append(slice, 4, 5)
fmt.Println("切片:", slice)
// Map
m := map[string]int{
"apple": 5,
"banana": 3,
}
m["orange"] = 4
fmt.Println("Map:", m)
// 结构体
type Person struct {
Name string
Age int
}
p := Person{Name: "Alice", Age: 30}
fmt.Printf("Person: %+v\n", p)
// 指针
x := 42
p2 := &x
*p2 = 21
fmt.Println("x 的值:", x)
}下一步
接下来我们将学习:
