主线剧情
在我们写代码的过程中,经常使用到len求集合类型的长度。
func len(v Type) int
那你有没有想过,为何len的返回值类型是int。
要知道golang的数值类型,分为有符号整数和无符号整数类型。
有符号类型:int8/int16/int32/int64
无符号类型:uint8/uint16/uint32/uint64
对于一个集合的长度,肯定是非负数,用uint就行吧~
真的吗?
我们来看一个例子
func main() {
//
var nums = []int{1, 2, 3, 4}
// 倒序遍历数组
for i := lenUInt(nums) - 1; i >= 0; i-- {
fmt.Printf("i:%d -> num:%d\n", i, nums[i])
}
}
// 简单实现一个返回uint的len函数
func lenUInt(v []int) uint {
return uint(len(v))
}
各位思考一下,上面的代码能够成功执行码?
不能!
i:3 -> num:4
i:2 -> num:3
i:1 -> num:2
i:0 -> num:1
panic: runtime error: index out of range [18446744073709551615] with length 4
因为uint总是大于等于0的,
0-1不等于-1,遍历永远不会停止,或者panic。
这下大家明白了吧。
len返回int而不是uint,是因为uint可能会造成灾难性后果
支线剧情
当然len(v)会根据v的类型,做出不同的回应。
查看golang的官方文档,如下
Array: the number of elements in v.
Pointer to array: the number of elements in *v (even if v is nil).
Slice, or map: the number of elements in v; if v is nil, len(v) is zero.
String: the number of bytes in v.
Channel: the number of elements queued (unread) in the channel buffer;
if v is nil, len(v) is zero.