在 Go 中,len() 返回字节切片当前元素个数(即逻辑长度,单位:字节),cap() 返回底层数组可容纳的最大字节数;二者均以字节为单位,无需额外计算,且 byte 类型严格保证为 1 字节宽。
在 go 中,`len()` 返回字节切片当前元素个数(即逻辑长度,单位:字节),`cap()` 返回底层数组可容纳的最大字节数;二者均以字节为单位,无需额外计算,且 `byte` 类型严格保证为 1 字节宽。
Go 语言中没有 C 风格的 sizeof() 运算符,但这并不意味着无法获取字节切片的“大小”——关键在于明确你所指的“大小”是逻辑数据量还是底层分配容量。
✅ 逻辑数据长度(已使用的字节数):使用 len(slice)。
对于 []byte,每个元素恒为 1 字节,因此 len(bs) 的返回值直接等于其占用的字节数,即有效载荷大小。✅ 底层底层数组总容量(可扩展的字节数上限):使用 cap(slice)。
它反映的是 make([]byte, len, cap) 中指定的容量,代表当前切片可追加而不触发扩容的最大字节数,也以字节为单位。
以下示例清晰展示了二者的区别:
// 创建一个长度为 1000、容量为 2000 的 []byte
bs := make([]byte, 1000, 2000)
fmt.Println("len(bs):", len(bs)) // 输出: 1000 → 当前实际使用的字节数
fmt.Println("cap(bs):", cap(bs)) // 输出: 2000 → 底层分配的总字节数(未被 slice 引用的部分仍可复用)
// 追加数据(不触发扩容)
bs = append(bs, make([]byte, 500)...)
fmt.Println("len(bs) after append:", len(bs)) // 输出: 1500
fmt.Println("cap(bs) unchanged:", cap(bs)) // 仍为 2000⚠️ 注意事项:
- len() 和 cap() 均为 O(1) 时间复杂度的内置函数,无运行时开销;
- 不要尝试用 unsafe.Sizeof(bs) 获取数据大小——它仅返回切片头(slice header)本身的大小(通常 24 字节:含指针、len、cap),完全不反映底层数据内存占用;
- Go 规范明确保证 byte 即 uint8,其大小恒为 1 字节(Size and alignment guarantees),因此 len([]byte) 的数值可直接等同于字节数,无需乘法换算。
总结:对于 []byte,len() 是获取当前数据体积的标准、高效且语义清晰的方式;若需评估内存预留量或预估扩容行为,则应关注 cap()。二者共同构成了 Go 中对切片内存规模的精准描述体系。










