在 Go 中,判断切片长度和容量最直接的方式是使用 len() 和 cap();若类型未知,则需用 reflect.Value 的 Len() 和 Cap() 方法,并注意 nil 切片和类型校验等陷阱。

在 Go 中,判断切片的长度和容量最直接的方式是使用内置函数 len() 和 cap()。但如果你需要在运行时对任意类型(比如通过接口或反射)进行动态检查,reflect.Value 就是关键工具。
基础方式:len() 和 cap() 直接获取
对已知类型的切片,无需反射:
-
len(s)返回当前元素个数(逻辑长度) -
cap(s)返回底层数组从切片起始位置开始可用的最大元素数(容量)
例如:
s := make([]int, 3, 5) // 长度3,容量5 fmt.Println(len(s), cap(s)) // 输出:3 5
使用 reflect.Value 获取长度和容量
当切片作为 interface{} 传入、或类型未知时,需用反射安全提取信息:
立即学习“go语言免费学习笔记(深入)”;
- 先用
reflect.ValueOf(v)获取值对象 - 检查是否为切片:
kind() == reflect.Slice - 调用
Len()和Cap()方法(注意大小写,反射方法首字母大写)
示例:
func inspectSlice(v interface{}) (length, capacity int) {
rv := reflect.ValueOf(v)
if rv.Kind() != reflect.Slice {
return 0, 0
}
return rv.Len(), rv.Cap()
}
s := []string{"a", "b"}
l, c := inspectSlice(s) // l=2, c=2
注意事项与常见陷阱
使用反射时容易出错的地方:
- 传入 nil 切片时,
reflect.ValueOf(nil)的Kind()是reflect.Invalid,不是reflect.Slice,需先判空 - 不能对未导出字段(小写开头)的结构体切片字段直接反射取值,需确保可寻址或已导出
-
reflect.Value.Len()对非 slice/map/array 类型 panic,务必先Kind()校验
扩展:检查是否为有效切片(含 nil 安全)
更健壮的反射判断方式:
func safeSliceInfo(v interface{}) (ok bool, length, capacity int) {
rv := reflect.ValueOf(v)
if rv.Kind() == reflect.Slice {
return true, rv.Len(), rv.Cap()
}
if rv.Kind() == reflect.Ptr && !rv.IsNil() {
elem := rv.Elem()
if elem.Kind() == reflect.Slice {
return true, elem.Len(), elem.Cap()
}
}
return false, 0, 0
}
该函数支持直接传切片或指向切片的指针,也兼容 nil 指针保护。










