len()对数组返回编译期确定的固定长度,是类型的一部分;对切片返回运行时可变的当前元素个数;不支持struct等类型,误用会编译失败。

len() 能直接获取数组长度,但要注意它返回的是编译期确定的固定值
Go 中的数组是值类型,长度是其类型的一部分。这意味着 len() 对数组求长度时,不是运行时计算,而是直接读取类型信息——所以它极快,且不可能 panic。
比如 [5]int 和 [10]int 是两种完全不同的类型,len() 返回的 5 或 10 在编译时就已固化。
- 数组声明后长度不可变:
var a [3]string→len(a)永远是3 - 不能对未定义长度的数组(如
[...]int{1,2,3})用len()做“动态推导”——它照样返回推导出的常量值(这里是3) - 切片也能用
len(),但行为完全不同:它返回当前元素个数(运行时可变),别和数组混淆
别把 slice 当成 array 用 len(),否则可能误判实际元素数
新手常写 var s []int = make([]int, 0, 5),然后以为 len(s) 是 5 ——其实它是 0。因为 len() 对切片返回的是“当前长度”,不是底层数组容量。
典型错误场景:初始化一个空切片后循环填充,却用 len() 判断是否填满,结果永远进不了循环体。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
-
make([]int, 3)→len()返回3(预分配并初始化了 3 个零值) -
make([]int, 0, 3)→len()返回0,cap()才是3 - 从数组转切片:
a := [4]int{1,2,3,4}; s := a[:2]→len(s)是2,不是4
函数参数接收数组时,len() 返回值取决于形参声明的数组长度
如果函数签名写的是 func f(a [5]int),那在函数体内调用 len(a) 永远是 5,哪怕你传入的是 [5]int{} 或 [5]int{1} ——因为类型已锁死。
这和传切片 func f(s []int) 完全不同:后者 len(s) 随实参变化。
- 想写通用长度处理?别用数组作参数,改用切片
- 必须用数组(比如需要值拷贝或栈上分配)?那就接受长度固定的事实,
len()就是类型契约的一部分 - 误把
[...]T字面量当可变长数组传参?不行:[...]int{1,2,3}类型是[3]int,仍受长度绑定
len() 不支持 map、channel、struct 等其他类型,用错会编译失败
Go 的 len() 是内置函数,只对字符串、数组、切片、map 和 channel 有效。但对 struct、指针、自定义类型等直接调用会报错:invalid argument ... (type XXX) for len。
尤其注意:map 的 len() 返回键值对数量,channel 的 len() 返回当前缓冲队列中元素个数(非容量),这两个容易被忽略语义差异。
- 对 struct 调
len()?编译报错:invalid argument s (type MyStruct) for len - 对 nil slice 或 nil map 调
len()是安全的,返回0;但对 nil channel 调len()也合法,返回0 - 不要试图用
len()推断 struct 字段数——Go 没有反射式元信息暴露机制,得靠reflect.TypeOf(x).NumField()
len() 在不同类型上有统一行为,是多数困惑的源头。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










