【问题标题】:Re-slicing slices in Golang在 Golang 中重新切片
【发布时间】:2012-09-27 22:30:02
【问题描述】:

我最近学习了 Go 语言,现在我对以下代码感到困惑:

package main

import "fmt"

func main() {
    a := make([]int, 5)
    printSlice("a", a)
    b := make([]int, 0, 5)
    printSlice("b", b)
    c := b[:2]
    printSlice("c", c)
    d := c[2:5]
    printSlice("d", d)
}

func printSlice(s string, x []int) {
    fmt.Printf("%s len=%d cap=%d %v\n",
        s, len(x), cap(x), x)
}

结果:

a len=5 cap=5 [0 0 0 0 0]
b len=0 cap=5 []
c len=2 cap=5 [0 0] //why the capacity of c not 2 but 5 instead
d len=3 cap=3 [0 0 0]

【问题讨论】:

  • 具有自己容量的切片即将推出(转到 1.2)。见my answer below

标签: arrays slice


【解决方案1】:

c 是取自数组b 的切片。这不是副本,而只是 b 的前 2 个元素上的一个窗口。

由于b 的容量为 5,c 可以扩展到其他 3 个位置(实际上它创建了一个新切片,但位于内存中的同一位置)。

切片的最大容量是底层数组的容量减去数组中切片开始的位置:

 array : [0 0 0 0 0 0 0 0 0 0 0 0]
 array :  <----   capacity   --->
 slice :     [0 0 0 0]
 slice :      <---- capacity ---> 

也许这个程序会更清楚地表明 c 和 d 只是 b 上的窗口:

func main() {
    b := make([]int, 0, 5)
    c := b[:2]
    d := c[1:5] // this is equivalent to d := b[1:5]
    d[0] = 1
    printSlice("c", c)
    printSlice("d", d)
}

输出:

c len=2 cap=5 [0 1] // modifying d has modified c
d len=4 cap=4 [1 0 0 0] 

【讨论】:

  • 感谢您的帮助。
  • 那么b也会受到影响?
  • 是的。但是你不会看到它,因为长度是 0。
【解决方案2】:

请注意,在 go 1.2 (Q4 2013, 1.2rc1 is available now) 中,您可以将其自己的容量关联到切片(而不是从底层数组推导出的容量)。

请参阅“Three-index slices”和design document。

切片操作通过描述已创建的数组或切片的连续部分来创建新切片:

var array [10]int
slice := array[2:4]

切片的容量是切片可以容纳的最大元素数,即使在重新切片之后;它反映了底层数组的大小。
在本例中,切片变量的容量为 8。

(底层数组的容量减去数组中切片开始的位置)

array : [0 0 0 0 0 0 0 0 0 0]
 array : <---- capacity --->
 slice :    [0 0]
 slice :    <-- capacity --> 8 (10-2)

Go 1.2 添加了新语法以允许切片操作指定容量和长度。
第二个冒号引入容量值,该值必须小于或等于源切片或数组的容量,针对原点进行调整。

例如,

slice = array[2:4:6]

array : [0 0 0 0 0 0 0 0 0 0]
 array : <---- capacity --->   10
 slice :    [0 0]
 slice :    <- cap->           4 (6-2)

将切片设置为与前面示例中相同的长度,但其容量现在只有 4 个元素 (6-2)。
无法使用此新切片值访问最后两个元素原始数组的元素。

主要论点是让程序员更多地控制append。

a[i : j : k]

那个切片有:

  • 从 0 开始的索引
  • 长度等于j - i
  • 容量等于k - i

如果i &lt;= j &lt;= k &lt;= cap(a) 不为真,评估会出现混乱。

【讨论】:

    猜你喜欢
    • 2018-04-15
    • 1970-01-01
    • 1970-01-01
    • 2021-07-14
    • 2019-10-17
    • 1970-01-01
    • 2017-06-17
    • 2020-12-09
    • 2014-11-01
    相关资源
    最近更新 更多