golang 切片,用 slice[a:b:c] 切片

golang slice, slicing a slice with slice[a:b:c]

我读过 go slice usage and internals and Slice and Effective go#slice 但没有像这样用 3 个数字切片的方法:slice[a:b:c]

例如这段代码:

package main

import "fmt"

func main() {
    var s = []string{"a", "b", "c", "d", "e", "f", "g"}
    fmt.Println(s[1:2:6], len(s[1:2:6]), cap(s[1:2:6]))
    fmt.Println(s[1:2:5], len(s[1:2:5]), cap(s[1:2:5]))
    fmt.Println(s[1:2], len(s[1:2]), cap(s[1:2]))

}

go playground 结果是这样的:

[b] 1 5
[b] 1 4
[b] 1 6

我能理解第三个是关于容量的东西,但是这个具体是什么意思呢?
我是否遗漏了文档中的内容?

Go 1.2 引入了语法,正如我在“Re-slicing slices in Golang”中提到的。
它记录在 Full slice expressions:

a[low : high : max]

constructs a slice of the same type, and with the same length and elements as the simple slice expression a[low : high].
Additionally, it controls the resulting slice's capacity by setting it to max - low.
Only the first index may be omitted; it defaults to 0.

After slicing the array a:

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

the slice t has type []int, length 2, capacity 4, and elements

t[0] == 2
t[1] == 3

该功能的 design document 具有以下理由:

It would occasionally be useful, for example in custom []byte allocation managers, to be able to hand a slice to a caller and know that the caller cannot edit values beyond a given subrange of the true array.

The addition of append to the language made this somewhat more important, because append lets programmers overwrite entries between len and cap without realizing it or even mentioning cap.

在切片表达式中 slice[a:b:c]aSlice[1:3:5]

a:b or 1:3 -> gives length
a:c or 1:5 -> gives capacity

我们可以从带有 3 numbers/indices 的切片表达式中提取 lengthcapacity,而无需查看源代码 slice/array.

expression| aSlice[low:high:max]  or aSlice[a:b:c]    or aSlice[1:3:7]
------------------------------------------------------------------------
Length    | len(aSlice[low:high]) or len(aSlice[a:b]) or len(aSlice[1:3])
Capacity  | len(aSlice[low:max])  or len(aSlice[a:c]) or len(aSlice[1:7])
------------------------------------------------------------------------

Slice Expressions

上阅读更多内容

Playground

实际上 Go slice 有一个指针并指向数组,它保存数组的长度和容量,我们可以像下面那样显示它

指针:长度:容量

追加用于添加相同的新长度。

    sl1 := make([]int, 6)
    fmt.Println(sl1)

    sl2 := append(sl1, 1)
    fmt.Println(sl2)
[0 0 0 0 0 0]
[0 0 0 0 0 0 1]