为了账号安全,请及时绑定邮箱和手机立即绑定

为什么 go 允许从 len(slice) 切片?

为什么 go 允许从 len(slice) 切片?

Go
aluckdog 2021-10-04 17:27:44
为什么会出现以下行为:a := []int{1, 2, 3}fmt.Println(a[0:])fmt.Println(a[1:])fmt.Println(a[2:])fmt.Println(a[3:])// doesn't panic - why??fmt.Println(a[4:])// panics as expected
查看完整描述

3 回答

?
守候你守候我

TA贡献1802条经验 获得超10个赞

引用规范:切片表达式

对于数组或字符串,如果,则索引在范围内0 <= low <= high <= len(a),否则它们超出范围。对于切片,索引上限是切片容量cap(a)而不是长度。

所以本说明书中允许使用指数高达len(a)底层的阵列len(a) 包括(或cap(a)在在这种情况下具有相同的值的切片的情况下)。这就是为什么a[3:]在你的情况下不恐慌。

但它当然会产生一个空切片,因为:

a[low : high]

意味着结果的索引从 at 开始,0长度等于high - lowand 由于high被省略,它默认为len(a)so len(a) - len(a) = 0

而且(根据规范)使用索引> len(a) 将超出范围,因此会导致运行时恐慌:

如果索引在运行时超出范围,则会发生运行时恐慌


查看完整回答
反对 回复 2021-10-04
?
慕姐4208626

TA贡献1852条经验 获得超7个赞

a[3:] 构建一个空切片,它就像一个空数组一样,是一个有效且有用的对象(在所有语言中,不仅仅是在 Go 中)。


空切片也仍然指向底层数组、位置和容量,有时可以扩展:


a := []int{1, 2, 3}

emptySlice := a[1:1]

fmt.Println(emptySlice) // []

notEmpty := emptySlice[0:2]

fmt.Println(notEmpty)   // [2 3]

另一方面,具有负长度的切片是不一致的。它没有任何意义,因此被禁止。


查看完整回答
反对 回复 2021-10-04
?
郎朗坤

TA贡献1921条经验 获得超9个赞

因为在切片中有0元素 ( 3-3) 是完全有效的。但是有-1元素 ( 3-4) 不是。


这种行为也与其他语言一致。例如,Java:


System.out.println(Arrays.asList(1, 2, 3).subList(0, 3));

System.out.println(Arrays.asList(1, 2, 3).subList(1, 3));

System.out.println(Arrays.asList(1, 2, 3).subList(2, 3));

System.out.println(Arrays.asList(1, 2, 3).subList(3, 3));

System.out.println(Arrays.asList(1, 2, 3).subList(4, 3));

只有最后一个语句失败。


查看完整回答
反对 回复 2021-10-04
  • 3 回答
  • 0 关注
  • 248 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信