数组长度是类型的一部分,切片不是;声明[3]int和[4]int不兼容,不能赋值;切片[]int类型统一,可自由传参;除非需固定长度语义,否则函数参数一律用[]t;数组传参拷贝全部元素,切片只拷贝24字节header。
数组长度是类型的一部分,切片不是
这是最直接影响编译和赋值行为的区别。声明 [3]int 和 [4]int 是两个完全不兼容的类型,不能互相赋值或传参:
-
var a [3]int和var b [4]int——a = b直接报错:cannot use b (variable of type [4]int) as [3]int value -
[]int无论背后是 5 个还是 500 个元素,类型始终是[]int,可自由赋值、传参、返回
所以函数参数该用数组还是切片?除非你**明确需要固定长度语义**(比如处理 16 字节 UUID 或 RGB 像素),否则一律用 []T —— 否则每次改个长度就得改函数签名。
传参时数组拷贝整个内存,切片只拷贝头结构
数组是值类型,传参即复制全部元素;切片是引用类型,传参只复制 24 字节的 header(指针 + len + cap):
- 传
[1000]int进函数:栈上拷贝 8KB(假设 int64),开销大且无必要 - 传
[]int进函数:只拷贝 header,原底层数组仍在堆上,修改元素会影响调用方
注意:这不是“传引用”或“传指针”的语法糖,而是底层结构决定的——slice 结构体里本身就含指针字段。所以别写 *[]int,那是套娃,通常没意义。