Go语言学习笔记(三)——数组、切片、Map 与结构体深入理解

在 Go 的基础语法中,数组、切片、map 和结构体是使用频率极高的核心内容。真正写项目时,数据组织和数据处理几乎都离不开它们。

一、数组 Array

数组是固定长度、相同类型元素的集合。

var arr [3]int = [3]int{1, 2, 3}
fmt.Println(arr)

也可以简写:

arr := [3]int{1, 2, 3}

数组长度是类型的一部分,也就是说 [3]int[4]int 是不同类型。

访问元素:

fmt.Println(arr[0])
arr[1] = 100
fmt.Println(arr)

遍历数组:

for i := 0; i < len(arr); i++ {
    fmt.Println(arr[i])
}

或者:

for index, value := range arr {
    fmt.Println(index, value)
}

数组的缺点很明显:长度固定,不够灵活。因此在实际开发中,更多使用的是切片。

二、切片 Slice

切片可以理解为对数组的动态封装,是 Go 中极其重要的数据结构。

1. 切片定义

nums := []int{1, 2, 3, 4, 5}

与数组不同,切片不需要写固定长度。

2. 切片截取

arr := [5]int{10, 20, 30, 40, 50}
s := arr[1:4]
fmt.Println(s)

这里会得到:

[20 30 40]

规则是:左闭右开,包含起始下标,不包含结束下标。

3. len 和 cap

切片有两个重要属性:

  • len:当前长度
  • cap:容量
s := []int{1, 2, 3}
fmt.Println(len(s))
fmt.Println(cap(s))

4. append 添加元素

s := []int{1, 2, 3}
s = append(s, 4)
s = append(s, 5, 6)
fmt.Println(s)

5. make 创建切片

s := make([]int, 3, 5)
fmt.Println(s)
fmt.Println(len(s), cap(s))

这里表示创建一个长度为 3、容量为 5 的切片。

6. 切片是引用类型

切片本质上指向底层数组,因此赋值或传参时需要注意共享数据的问题。

a := []int{1, 2, 3}
b := a
b[0] = 100
fmt.Println(a) // [100 2 3]

这说明 b 修改后,a 也受到影响。

三、Map 映射

map 是 Go 中的键值对数据结构,类似其他语言中的字典、哈希表。

1. map 定义

m := map[string]string{
    "name": "Tom",
    "city": "Beijing",
}
fmt.Println(m)

2. make 创建 map

m := make(map[string]int)
m["age"] = 20
m["score"] = 95

3. 访问 map

fmt.Println(m["age"])

如果 key 不存在,会返回值类型的零值。

4. 判断 key 是否存在

value, ok := m["age"]
if ok {
    fmt.Println("存在:", value)
} else {
    fmt.Println("不存在")
}

5. 删除元素

delete(m, "age")

6. 遍历 map

for k, v := range m {
    fmt.Println(k, v)
}

需要注意,Go 中 map 的遍历顺序是无序的,不能依赖固定顺序。

四、结构体 Struct

结构体用于组织不同类型的数据,是 Go 中实现复杂数据模型的重要方式。

1. 定义结构体

type Student struct {
    Name string
    Age  int
    Score float64
}

2. 创建结构体对象

s1 := Student{
    Name: "Alice",
    Age:  20,
    Score: 95.5,
}
fmt.Println(s1)

也可以这样写:

var s2 Student
s2.Name = "Bob"
s2.Age = 21
s2.Score = 88.5

3. 结构体指针

s := &Student{
    Name: "Tom",
    Age:  22,
}
fmt.Println(s.Name)

Go 对结构体指针访问成员做了语法简化,直接写 s.Name 即可,不需要 (*s).Name

五、结构体与切片、map 的结合

在实际开发中,经常把结构体放入切片或 map 中。

1. 结构体切片

students := []Student{
    {Name: "张三", Age: 18, Score: 90},
    {Name: "李四", Age: 19, Score: 85},
}
for _, stu := range students {
    fmt.Println(stu.Name, stu.Score)
}

2. 结构体 map

studentMap := map[string]Student{
    "001": {Name: "王五", Age: 20, Score: 92},
}
fmt.Println(studentMap["001"])

六、示例:学生信息管理基础版

package main

import "fmt"

type Student struct {
    Name  string
    Age   int
    Score float64
}

func main() {
    students := []Student{
        {"张三", 18, 88.5},
        {"李四", 19, 91.0},
        {"王五", 20, 85.0},
    }

    for _, stu := range students {
        fmt.Printf("姓名:%s,年龄:%d,成绩:%.1f\n", stu.Name, stu.Age, stu.Score)
    }
}

这个案例虽然简单,但已经体现了结构体和切片结合使用的方式,这种模式在项目中非常常见。

七、总结

数组适合处理固定长度数据,但在 Go 实际开发中使用频率不如切片。切片灵活、易扩展,是最常用的序列结构。map 适合做快速键值查询,而结构体则用于组织复杂数据模型。

可以说,切片、map 和结构体是 Go 编程的“三件套”。掌握了它们,写业务代码就有了基础框架。

posted @ 2026-03-13 21:44  空之匣  阅读(2)  评论(0)    收藏  举报