Go中的切片如何不取消引用?

ERJ*_*JAN -5 go slice

我已将问题作为注释包含在代码中。

我在这里看到不一致的地方。我们在这里做三片。在第一个切片s = s [:0]之后,s应该始终指向s [:0]。

package main

import "fmt"

func main() {
    s := []int{2, 3, 5, 7, 11, 13}
    printSlice(s)

    // Slice the slice to give it zero length.
    //1
    s = s[:0]
    printSlice(s) //after we do this, should not the var s always point to s[:0]?

    // Extend its length.
    s = s[:4]
    printSlice(s) //here, how is this s pointing back to original s? we just changed it to be s = s[:0]

    // Drop its first two values.
    s = s[2:]     //yet here we somehow refer to only the portion from s[:4]
    printSlice(s)  
}

func printSlice(s []int) {
    fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}
Run Code Online (Sandbox Code Playgroud)

输出:

len=6 cap=6 [2 3 5 7 11 13]
len=0 cap=6 []         // slice s[:0]  
len=4 cap=6 [2 3 5 7]  // slice s[:4] - here we refer to the whole array s
len=2 cap=4 [5 7]      // slice s[2:] - here we refer not to the whole array s, but to the part we got from s[:4], which is contradiction to s[:0]
Run Code Online (Sandbox Code Playgroud)

希望它不要太混乱。

Adr*_*ian 6

切片是基础数组的视图。无论您如何重新切片,它仍然是相同的基础数组。如果您采用同一数组的两个切片,则它们都将具有相同的基础数组,例如:https : //play.golang.org/p/T-hYDWeo2TK

initial := []string{"foo", "bar", "baz"}
s1 := initial[:1]
initial[0] = "qux"
fmt.Println(s1)
Run Code Online (Sandbox Code Playgroud)

[qux]

Go博客文章Go Slices中的大量示例对此进行了详细解释:用法和内部原理

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

因此,您可以继续制作具有不同长度/容量/起始索引但具有相同阵列的不同切片。它们只是同一阵列上的不同视图。