切片的cap()是如何计算的?

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

How cap() of slice calculated?

问题

在下面的代码中:

package main

import "fmt"

func main() {

    b := make([]int, 0, 5)
    fmt.Println(len(b), cap(b), b) // 0 5

    c := b[:3]
    fmt.Println(len(c), cap(c), c) // 3 5

    d := c[1:5]
    fmt.Println(len(d), cap(d), d) // 4 4

    e := d[0:4]
    fmt.Println(len(e), cap(e), e) // 4 4

}

d的底层数组与bc的底层数组相同。

为什么cap(d)是4?

英文:

In the below code:

package main

import "fmt"

func main() {

	b := make([]int, 0, 5)
	fmt.Println(len(b), cap(b), b) // 0 5

	c := b[:3]
	fmt.Println(len(c), cap(c), c) // 3 5

	d := c[1:5]
	fmt.Println(len(d), cap(d), d) // 4 4

	e := d[0:4]
	fmt.Println(len(e), cap(e), e) // 4 4

}

underlying array for d is same as underlying array for b & c

Why cap(d) is 4?

答案1

得分: 1

让我们一步一步来解释。

初始化 b

b := make([]int, 0, 5) // 创建一个长度为0,容量为5的切片

fmt.Println(len(b), cap(b), b) // 输出 0 5

b => c

c := b[:3] // 创建一个长度为3,容量仍为5的切片

fmt.Println(len(c), cap(c), c) // 输出 3 5

c => d

d := c[1:5] // 创建一个长度为4,容量为4的切片

fmt.Println(len(d), cap(d), d) // 输出 4 4

c[1:5] 之所以使容量减少了一个,是因为它实际上从数组中删除了 c[0]... 它被完全切片掉了。

可视化

数组长度为5
-------------
[ 0 0 0 0 0 ]
  0 1 2 3 4

c[1:5] = [ x | 0 0 0 0 ]
           ^
           这个索引在切片后面,被切片掉了,所以新的容量是基于数组 [ 0 0 0 0 ]
                                                          1 2 3 4


为什么其他情况没有发生这种情况呢...?
-------------------------------------------
b[:3] = [ 0 0 0 | x x ]
                  ^ ^
                  这两个索引没有落在切片后面,所以容量仍然是5 [ 0 0 0 x x ]
                                                       1 2 3 4 5

英文:

lets break it down step by step

intialized b

b := make([]int, 0, 5) // which makes [ ] = length 0, with a cap of 5

fmt.Println(len(b), cap(b), b) // 0 5

b => c

c := b[:3] // which makes [ 0 0 0 ] = length 3, still a cap of 5

fmt.Println(len(c), cap(c), c) // 3 5

c => d

d := c[1:5] // which makes [ 0 0 0 0 ] = length of 4, now with a cap of 4

fmt.Println(len(d), cap(d), d) // 4 4

the reason for c[1:5] making the cap one less because it's technically erasing c[0] from the array... it's being completely sliced out of it.

visualization

array of 5
-------------
[ 0 0 0 0 0 ]
  0 1 2 3 4

c[1:5] = [ x | 0 0 0 0 ]
           ^
           this index of the array fell behind the sliced indexs and was 
           sliced out making the new cap is based off the array [ 0 0 0 0 ]
                                                                  1 2 3 4


why didnt this happen with the others...?
-------------------------------------------
b[:3] = [ 0 0 0 | x x ]
                  ^ ^
                  these two indexs of the array did not fall behind the
                  sliced indexs which means the cap remains at 5 [ 0 0 0 x x ]
                                                                   1 2 3 4 5

huangapple
  • 本文由 发表于 2022年5月31日 12:14:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/72442228.html
匿名

发表评论

匿名网友

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

确定