我看过go slice usage and internals和Slice以及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
我能理解第三个是关于容量的东西,但这个的确切含义是什么? 我是否遗漏了文件中的内容?
答案 0 :(得分:11)
语法已在Go 1.2中引入,正如我在" Re-slicing slices in Golang"中提到的那样。 它记录在Full slice expressions:
中a[low : high : max]
构造一个相同类型的切片,其长度和元素与简单切片表达式
a[low : high]
相同。
此外,它通过将切片的容量设置为max - low
来控制切片的容量 只能省略第一个索引;它默认为0.切片后
a
:
a := [5]int{1, 2, 3, 4, 5}
t := a[1:3:5]
切片t的类型为[] int,长度为2,容量为4,元素为
t[0] == 2
t[1] == 3
该功能的design document具有以下理由:
有时,例如在自定义
[]byte
分配管理器中,能够将切片传递给调用者并知道调用者无法编辑超出真实数组的给定子范围的值。在语言中添加
append
会使这一点变得更加重要,因为append
允许程序员覆盖len
和cap
之间的条目,而不会意识到它甚至提到cap
。
答案 1 :(得分:1)
Go release notes中对此进行了很好的解释。 请注意,缺少的第一个索引([:0:0])默认为零。
答案 2 :(得分:0)
a:b -> length
a:c -> capacity
我们可以从具有3个索引的切片表达式中提取length
和capacity
,而无需查看源切片/数组。
A slice 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])
处了解更多信息。
答案 3 :(得分:0)
实际上Go切片有一个指向数组的指针,它持有数组的长度和容量,我们可以像这样显示它
pointer:length:capacity
和append用于添加相同的新长度。
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]