Go语言数组与切片的区别

数组与切片的区别

一句话结论:

数组是"值类型容器"
切片是"指向数组的引用视图"

再直白一点:

  • 数组:我自己就是数据

  • 切片:我只是看数据的一扇窗

  • 数组 = 盒子

  • 切片 = 指向盒子的标签

  • 复制盒子 → 内容独立

  • 复制标签 → 看同一个盒子

一、最本质的 4 个区别(核心)

|---------|---------------|---------------|
| 对比点 | 数组(array) | 切片(slice) |
| 类型 | 值类型 | 引用语义(结构体) |
| 长度 | 固定,类型的一部分 | 可变 |
| 内存 | 自己持有数据 | 指向底层数组 |
| 常用性 | 很少直接用 | Go 的主力 |

二、类型层面的区别(非常关键)

数组:长度是类型的一部分

复制代码
var a [3]int
var b [4]int

👉 a 和 b 是完全不同的类型

复制代码
a = b // ❌ 编译错误

切片:长度不是类型的一部分

复制代码
var s1 []int
var s2 []int

👉 无论多长,类型都一样

三、内存模型区别(理解一切 bug 的根源)

数组(独立内存)

复制代码
a := [3]int{1, 2, 3}
b := a
b[0] = 100

结果:

复制代码
a = [1 2 3]
b = [100 2 3]

👉 值拷贝

切片(共享底层数组)

复制代码
a := []int{1, 2, 3}
b := a
b[0] = 100

结果:

复制代码
a = [100 2 3]
b = [100 2 3]

👉 共享底层数组

四、作为函数参数的区别

数组传参:完整拷贝(非常重)

复制代码
func f(a [3]int) {
    a[0] = 100
}

func main() {
    x := [3]int{1, 2, 3}
    f(x)
    fmt.Println(x)
}

输出:

复制代码
[1 2 3]

切片传参:拷贝 slice 头(轻)

复制代码
func f(s []int) {
    s[0] = 100
}

func main() {
    x := []int{1, 2, 3}
    f(x)
    fmt.Println(x)
}

输出:

复制代码
[100 2 3]

五、长度与容量(数组没有 cap)

复制代码
a := [3]int{1, 2, 3}

len(a) // 3
cap(a) // ❌ 不存在

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

len(s) // 3
cap(s) // >= 3

👉 cap 是 slice 独有的概念

六、创建方式差异

数组(少见)

复制代码
a := [3]int{1, 2, 3}
a := [...]int{1, 2, 3} // 编译期推断

切片(主流)

复制代码
s := []int{1, 2, 3}
s := make([]int, 3)
s := make([]int, 0, 10)

七、为什么 Go 设计数组 + 切片两套?

一句话:

数组用于"确定大小的数据结构"
切片用于"动态、高效的数据处理"

数组适合:

  • 小型、固定大小
  • 值语义(拷贝安全)
  • 底层数据结构(如哈希桶)

切片适合:

  • 几乎所有业务代码
  • 传参
  • 集合、列表、缓冲区

八、工程级使用建议

✅ 99% 场景用切片

复制代码
func process(data []byte)

✅ 用数组的 3 种典型场景

1️⃣ 编译期固定大小

复制代码
var buf [32]byte // hash / uuid

2️⃣ 明确要值语义

复制代码
type Point struct {
    XY [2]int
}

3️⃣ 性能 / 底层库

复制代码
var table [256]byte
相关推荐
胡马北风Norstead15 小时前
企业级门户网站设计与实现:基于SpringBoot + Vue3的全栈解决方案(Day 7)
后端
kyriewen1115 小时前
Next.js部署:从本地跑得欢,到线上飞得稳
开发语言·前端·javascript·科技·react.js·前端框架·ecmascript
AI人工智能+电脑小能手15 小时前
【大白话说Java面试题】【Java基础篇】第21题:HashMap和Hashtable的区别是什么
java·开发语言·面试·哈希算法·散列表·hash table
不想写代码的星星15 小时前
COW(Copy-on-Write):开抄开抄,哎嘿,我装的
开发语言·c++
慕容卡卡15 小时前
Claude 使用神器(web页面)--CloudCLI UI
java·开发语言·前端·人工智能·ui·spring cloud
咬_咬15 小时前
go语言学习(函数)
开发语言·学习·golang
fliter15 小时前
Cloudflare 防火墙规则背后的工程实践
后端
froginwe1115 小时前
PHP MySQL Delete 操作指南
开发语言
凯瑟琳.奥古斯特15 小时前
图论核心考点精讲
开发语言·数据结构·算法·排序算法·哈希算法
charlie11451419115 小时前
嵌入式Linux驱动开发(8)——内存映射 I/O - 别拿物理地址当指针用
linux·开发语言·驱动开发·c·imx6ull