英文:
golang slice, slicing a slice with slice[a:b:c]
问题
我阅读了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
我可以理解第三个结果与容量有关,但确切的含义是什么?
我是否在文档中遗漏了什么?
英文:
I read go slice usage and internals and Slice and Effective go#slice but there is nothing about slicing a slice with 3 number like this : slice[a:b:c]
For example this code :
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 result is this :
[b] 1 5
[b] 1 4
[b] 1 6
I can understand that the third one is something about capacity, but what is the exact meaning of this?
Do I miss something in documents?
答案1
得分: 62
这个语法在Go 1.2中引入,正如我在"在Golang中重新切片切片"中提到的那样。它在完整切片表达式中有详细说明:
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
该功能的设计文档中有以下解释:
有时候会有用处,例如在自定义的
[]byte
分配管理器中,可以将一个切片传递给调用者,并确保调用者无法编辑真实数组的给定子范围之外的值。
append
语言的添加使得这个功能变得更加重要,因为**append
允许程序员在不意识到或甚至提及cap
的情况下覆盖len
和cap
之间的条目**。
2022年:svitanok为Go 1.19+添加了以下内容:
虽然“派生”切片的容量在创建时不会超过第三个索引指定的容量,但该切片仍然“来自”与其原始(“真实”)切片相同的内存位置,因此对其进行的更改将影响原始切片。
如果然后,例如,您向这个派生切片追加了导致其容量增加的元素数量,这个新切片将占据内存中的不同位置,因此对其进行的更改将不会影响它所起源的切片。
英文:
The syntax has been introduced in Go 1.2, as I mentioned in "Re-slicing slices in Golang".
It is documented in 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
> t1 == 3
The design document for that feature had the following justification:
> 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
.
2022: svitanok adds for Go 1.19+:
> while the capacity of a "derivative" slice doesn't exceed the one specified by the third index during its creation the slice is still "from" the same spot in the memory as its original ("true") slice, so the changes applied to it will affect the original slice.
>
> And if then, for example, you append to this derivative slice the amount of elements that would cause its capacity to be increased, this new slice will occupy a different place in the memory, and so the changes made to it will not affect the slice it originated from.
答案2
得分: 8
在切片表达式slice[a:b:c]
或aSlice[1:3:5]
中,
a:b或1:3 -> 给出长度
a:c或1:5 -> 给出容量
我们可以从具有3个数字/索引的切片表达式中提取长度
和容量
,而无需查看源切片/数组。
表达式| aSlice[low:high:max] 或 aSlice[a:b:c] 或 aSlice[1:3:7]
------------------------------------------------------------------
长度 | len(aSlice[low:high]) 或 len(aSlice[a:b]) 或 len(aSlice[1:3])
容量 | len(aSlice[low:max]) 或 len(aSlice[a:c]) 或 len(aSlice[1:7])
------------------------------------------------------------------
在Slice Expressions中了解更多信息
英文:
In a slice expression slice[a:b:c]
or aSlice[1:3:5]
a:b or 1:3 -> gives length
a:c or 1:5 -> gives capacity
We can extract both length
and capacity
from a slice expression with 3 numbers/indices, without looking at the source 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])
------------------------------------------------------------------------
Read more here at Slice Expressions
答案3
得分: -1
实际上,Go语言的切片(slice)包含一个指针,指向数组,并且它保存了数组的长度和容量。我们可以用以下格式表示:
指针:长度:容量
而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]
英文:
Actually Go slice have a pointer and pointing to the array and it holds length and capacity of the array and we can show it like will be
pointer:length:capacity
and append is used for adding same new length.
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]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论