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

Golang 子切片

Golang 子切片

Go
开心每一天1111 2022-06-27 17:06:33
在 Go 中,为什么这段代码有效:package mainimport (  "fmt")func main() {  a := []int{1}  a = a[1:]  fmt.Println(len(a))}但这不是:package mainimport (  "fmt")func main() {  a := []int{1}  a = a[2:]  fmt.Println(len(a))}我听说过切片的容量,有人可以详细说明吗?
查看完整描述

2 回答

?
达令说

TA贡献1821条经验 获得超6个赞

Go 规范包含两个问题的答案:

切片表达式

切片表达式从字符串、数组、指向数组的指针或切片构造子字符串或切片。有两种变体:一种是指定上限和下限的简单形式,另一种是指定容量界限的完整形式。

简单的切片表达式

[片段]

对于数组或字符串,索引在范围内if 0 <= low <= high <= len(a),否则超出范围

由于len(a)is 1,索引 1 在范围内,但索引 2 超出范围。

全切片表达式

对于数组、指向数组的指针或切片a(但不是字符串),主表达式

a[low : high : max]

构造一个与简单切片表达式具有相同类型、长度和元素的切片a[low : high]。此外,它通过将结果切片设置为 来控制结果切片的容量max - low。只有第一个索引可以省略;它默认为 0. ...

阅读整个规范。它可能会有点慢,但不会那么长。没有必要全部记住,但是通过一次完整的事情,你应该能够记住你在某个地方读过它,然后回去找到你要找的东西。


查看完整回答
反对 回复 2022-06-27
?
米琪卡哇伊

TA贡献1998条经验 获得超6个赞

切片的容量总是至少与切片的长度相同。未指定时,默认值始终与长度相同。

切片长度的定义是设置到切片中的元素个数。

切片容量的定义是切片可以提供的所有块,这些块对调用者是隐藏的,默认值为空(0 表示 int,“”表示字符串)。

当您像这样调用某个索引a[x]的值时,它将在 indexx的范围内获取值length

但是,当您像这样重新切片切片时a[x:y],它将在容量x范围内的索引处获得切片,直到 y(最大值必须与容量相同)。因此,作为切片的调用者,您可以在整个切片结构中获取切片的隐藏元素,默认值为空。

如果您没有像上面那样指定重新切片(y)的结束 -> a[2:],那么重新切片的默认结束将设置为lenght,这使您的调用a[2:]暗示a[2:1]自slice 的长度为 1。想想看,调用 的子切片a[2:1],会发生什么?正如错误消息告诉我们的那样:

恐慌:运行时错误:切片超出范围 [2:1]

因为您正在从甚至不在容量范围内的索引中调用子切片(它本身的切片的整个结构)。即使 2 在 slice 的容量范围内,您的调用也会重叠,因为起始索引大于容量。

总结一下:

  • 如果你像这样调用 sub-slice -> a[x:] 那么 x 必须在长度范围内(包括)

  • 如果你像这样调用 sub-slice -> a[:y] 那么 y 必须在容量范围内(包括)

  • 如果你像这样调用 sub-slice -> a[x:y] 那么 x 和 y 必须在容量(包括)和 x<=y 的范围内。


查看完整回答
反对 回复 2022-06-27
  • 2 回答
  • 0 关注
  • 224 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号