Go 切片已切片的引用

Go 切片已切片的引用,go,slice,Go,Slice,我正在参观Golang遗址,我正在尝试消化其中一个例子。目前尚不清楚其工作原理: package main import "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 =

我正在参观Golang遗址,我正在尝试消化其中一个例子。目前尚不清楚其工作原理:

package main

import "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个元素),而不是原始数组


有人能解释一下这两种情况之间的区别吗?

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

1) 当前使用的元素数以及

2) 容量,即其可占用的剩余长度

首先,我们创建一个包含6个整数的切片,这使得我们可以创建总大小为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
接下来我们说:使这个切片的
len
为0,这是
s=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
由于容量仍然相同,我们不妨通过说
s=s[:4]
将长度设为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://code>来获取一个子片,该子片不从内存的开头开始

       *  *
[0][1][2][3][4][5]
       ^
       s now points to the original address plus two!
len(s) = 2
cap(s) = 4

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

1) 当前使用的元素数以及

2) 容量,即其可占用的剩余长度

首先,我们创建一个包含6个整数的切片,这使得我们可以创建总大小为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
接下来我们说:使这个切片的
len
为0,这是
s=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
由于容量仍然相同,我们不妨通过说
s=s[:4]
将长度设为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://code>来获取一个子片,该子片不从内存的开头开始

       *  *
[0][1][2][3][4][5]
       ^
       s now points to the original address plus two!
len(s) = 2
cap(s) = 4
Leon把我发到Go的博客上,他们在那里正好回答了我的问题

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

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

一片不能长得超过它的容量。尝试这样做会导致运行时恐慌,就像在片或数组边界之外建立索引一样类似地,片不能在零以下重新切片以访问数组中的早期元素。

如果数组中有更多元素,则可以扩展切片,但不能访问切片0以下的元素。这是参考底图阵列的窗口。Leon在Go的博客上给我发了一封信,他们在那里准确地回答了我的问题

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

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

一片不能长得超过它的容量。尝试这样做会导致运行时恐慌,就像在片或数组边界之外建立索引一样类似地,片不能在零以下重新切片以访问数组中的早期元素。


如果数组中有更多元素,则可以扩展切片,但不能访问切片0以下的元素。这是参考底图阵列的窗口。更深入的解释。

官方golang博客上有一篇关于切片主题的博文,你可能会感兴趣。官方golang博客上有一篇关于切片主题的博文,你可能会感兴趣。谢谢你的回答,但我理解这部分。Leon提到的博客帖子有我问题的答案谢谢你的回答,但我理解这一部分。Leon提到的博客帖子回答了我的问题