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

切片切片参考

切片切片参考

Go
智慧大石 2023-04-04 14:14:23
我正在参观 Golang 网站,我正在尝试消化其中一个示例。目前还不清楚它是如何工作的:package mainimport "fmt"func main() {    s := []int{2, 3, 5, 7, 11, 13}    printSlice(s)    // Slice the slice to give it zero length.    s = s[:0]    printSlice(s)    // Extend its length.    s = s[:4]    printSlice(s)    // Drop its first two values.    s = s[2:]    printSlice(s)}func printSlice(s []int) {    fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)}输出是:len=6 cap=6 [2 3 5 7 11 13]len=0 cap=6 []len=4 cap=6 [2 3 5 7]len=2 cap=4 [5 7]在第一个切片之后,s = s[:0]切片长度为0。然后是另一个切片s = s[:4]。虽然长度为 0,但这似乎有效。但是这是怎么发生的呢?底层数组不应该可以从访问吗s?更让我困惑的是,下一次切片时,s = s[2:]我们切片的是 s 的旧值(有 4 个元素),而不是原始数组。有人可以阐明这两种情况有什么区别吗?
查看完整描述

2 回答

?
慕村9548890

TA贡献1884条经验 获得超4个赞

切片基本上是一个指向内存的指针,带有一些附加信息:


1)当前使用的元素数量和


2)容量,即它能占用的剩余长度。


一开始我们创建了一个包含 6 个整数的切片,这使得 go 也创建了总大小为 6 的底层 int 数组。


here is your memory locations with addresses (content does not matter here)

 *  *  *  *  *  *

[0][1][2][3][4][5]

 ^

 s points to the start of the memory

len(s) = 6

cap(s) = 6

接下来我们说:让这个slice'slen为0,这就是在位置0s = s[:0]处取一个长度为0的子切片。s注意s[0:0]是一样的,你可以省略第一个0。


[0][1][2][3][4][5]

 ^

 s still points to the start of the memory

len(s) = 0

cap(s) = 6

由于容量仍然相同,我们不妨将长度设为 4 s = s[:4]。


 *  *  *  *

[0][1][2][3][4][5]

 ^

 s still points to the start of the memory

len(s) = 4

cap(s) = 6

然后我们通过做一个不在内存开头的子切片s = s[2:]。


       *  *

[0][1][2][3][4][5]

       ^

       s now points to the original address plus two!

len(s) = 2

cap(s) = 4


查看完整回答
反对 回复 2023-04-04
?
函数式编程

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

这是帮助我更好地理解这个概念的片段:

切片是数组段的描述符。它由指向数组的指针、段的长度及其容量(段的最大长度)组成。

切片不能超出其容量。尝试这样做会导致运行时恐慌,就像索引超出切片或数组边界时一样。同样,不能将切片重新切片到零以下以访问数组中较早的元素。

如果数组中有更多元素,则可以扩展切片,但它不能访问切片 0 以下的元素。它是底层数组的窗口

查看完整回答
反对 回复 2023-04-04
  • 2 回答
  • 0 关注
  • 91 浏览
慕课专栏
更多

添加回答

举报

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