Skip to content

数据结构

数组

数组是固定长度的相同类型元素的序列。

声明和初始化

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)
}

下一步

接下来我们将学习:

基于 VitePress 构建