去切片 - 容量/长度?

时间:2016-04-18 00:56:59

标签: arrays go slice

试着学习现在的教程,并提出一个非常基本的问题:

 func main() {
  a := make([]int, 5)
  // [0,0,0,0,0] len=5 cap=5

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

  c := b[:2]
  // [0,0] len=2 cap=5

  d := c[2:5]
  // [0,0,0] len=3 cap=3
}

为什么c看起来像[0,0]并且长度为2? b原来没有归零,因此它是[]。那么将c设置为b[:2]会将前两个元素归零吗?

另外,为什么d 3的容量?很困惑。

提前致谢。

2 个答案:

答案 0 :(得分:9)

您的所有变量都有slice type。切片有一个支持array。在Go中,您无法访问未初始化的变量。如果在创建新变量时未明确提供值,则将使用变量类型的zero value初始化它们。

这意味着当您使用make([]int, 0, 5)创建切片时,它还会创建一个支持数组,支持数组将使用其零值进行初始化,此归零数组将为sliced。数组类型的零值是一个数组,其每个元素的元素类型为零值。

因此,即使您没有将支持数组的每个元素显式设置为0,它们也会自动归零。因此,当您执行c := b[:2]时,它会对b切片进行切片,c的长度为2,这2个元素将为0

当您对d := c[2:5]切片进行c切片时,其长度为5-2 = 3,其容量也为5-2 = 3,因为切片将导致一个新的共享相同的支持数组的切片,并且容量将是直到最后一个支持数组的第一个元素(除非你使用完整切片表达式,它也控制结果切片的容量。)

对于想要了解切片和数组的新手,必读博客文章:

The Go Blog: Go Slices: usage and internals

The Go Blog: Arrays, slices (and strings): The mechanics of 'append'

答案 1 :(得分:0)

官方文档提到了这一点。

切片的长度是其包含的元素数量。

切片的容量是从切片中的第一个元素开始计算的基础数组中元素的数量。

第一个问题:

为什么c看起来像[0,0]并且长度为2?

您的切片c是使用 b[:2]创建的,这意味着它具有切片b的从第0到第1位置的元素。因此,它只有2个元素,所以长度为2。

c设置为b[:2]也会使前两个元素归零吗?(因为b was []`)

现在,如@icza所述,go默认将它们初始化为0。通过设置c:=b[:2],您将b初始化为具有2个超出其容量5的元素。

第二个问题:

为什么d 3的容量

@Akavall的评论者之一。

capacity是切片可以访问的第一个元素与基础数组的最后一个元素之间的元素数量。

因此,在您的情况下,切片d可以访问的第一个元素是数组的第二个位置元素,而基础数组的最后一个元素是第5个位置。所以5-2是3。

我在此附加了访问数组的切片的正式图示。 enter image description here

切片的初始化和创建的更多示例在官方文档中进一步提供。 https://tour.golang.org/moretypes/13