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

huangapple go评论78阅读模式
英文:

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

问题

我阅读了go slice usage and internalsSliceEffective 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的情况下覆盖lencap之间的条目**。


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中了解更多信息

Playground

英文:

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

Playground

答案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]

huangapple
  • 本文由 发表于 2015年1月14日 15:55:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/27938177.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定