在Go语言中,有三种主要的容器类型用于存储和操作集合数据:数组(Array)、切片(Slice)和映射(Map)。
在 Go 语言中,有三种主要的容器类型用于存储和操作集合数据:数组(Array)、切片(Slice) 和 映射(Map)。以下是它们的详细说明和对比:
定义:
数组是具有 固定长度 的容器,存储相同类型的元素。长度在声明时确定,不可变。
特点:
声明与初始化:
// 声明长度为3的整型数组,默认初始化为零值
var arr1 [3]int
// 声明并初始化
arr2 := [3]int{1, 2, 3}
// 自动推断长度
arr3 := [...]int{4, 5, 6}
使用场景:
适合需要固定大小且对内存敏感的场合(如底层算法优化),但日常开发中较少直接使用。
定义:
切片是基于数组的 动态长度 抽象,提供更灵活的容器。切片本身是引用类型,底层指向一个数组。
特点:
append
函数)。声明与初始化:
// 直接声明切片(nil切片)
var s1 []int
// 通过数组创建切片
arr := [5]int{1, 2, 3, 4, 5}
s2 := arr[1:3] // 包含元素 [2, 3]
// 使用 make 创建切片
s3 := make([]int, 3, 5) // 长度3,容量5
// 直接初始化
s4 := []int{1, 2, 3}
常用操作:
s := []int{1, 2}
s = append(s, 3) // 追加元素 → [1, 2, 3]
sub := s[1:] // 截取子切片 → [2, 3]
使用场景:
绝大多数集合操作的默认选择(如动态列表、数据流处理)。
定义:
映射是 键值对(Key-Value) 的无序集合,通过哈希表实现,键必须可哈希(如 int
、string
)。
特点:
声明与初始化:
// 声明一个映射(nil映射,不可直接使用)
var m1 map[string]int
// 使用 make 初始化
m2 := make(map[string]int)
// 直接初始化
m3 := map[string]int{
"Alice": 25,
"Bob": 30,
}
常用操作:
m := map[string]int{}
m["Charlie"] = 28 // 添加或修改键值对
age, ok := m["Bob"] // 检查键是否存在(ok为bool)
delete(m, "Alice") // 删除键
使用场景:
快速查找、去重计数、配置管理等需要键值关联的场景。
特性 | 数组(Array) | 切片(Slice) | 映射(Map) |
---|---|---|---|
长度 | 固定 | 动态可变 | 动态可变 |
类型语义 | 值类型(复制整个数据) | 引用类型(共享底层数组) | 引用类型(共享存储) |
内存分配 | 编译时确定 | 运行时动态分配 | 运行时动态分配 |
访问方式 | 索引(0-based) | 索引(0-based) | 键(Key) |
主要用途 | 固定大小数据块 | 动态集合操作 | 键值对关联存储 |
切片共享底层数组:
多个切片可能共享同一底层数组,修改一个切片可能影响其他切片。
arr := [3]int{1, 2, 3}
s1 := arr[:] // s1 = [1,2,3]
s2 := s1[1:] // s2 = [2,3]
s2[0] = 100 // s1变为 [1,100,3]
映射的无序性:
遍历映射时,键值对的顺序不固定(Go 1.12+ 在扩容时随机化遍历顺序)。
并发安全:
切片和映射在并发读写时需加锁(或使用 sync.Map
)。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!