切片返回意外的长度。

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

Slices return unexpected length

问题

这是因为在创建month切片时,使用了索引为1的元素作为起始位置,而不是从索引0开始。这样做的结果是,切片的长度为12,但容量为13。切片的容量表示底层数组中从切片的起始位置到底层数组末尾的元素个数。在这种情况下,底层数组的长度为13,因此切片的容量也为13。

英文:

I’m studying Golang and I stopped by this and puzzled me.

package main

import "fmt"

func main() {
	month := [...]string{1: "Jan", 2: "Fab", 3: "March", 4: "April", 5: "May", 6: "June", 7: "July", 8: "Aug", 9: "Sep", 10: "Oct", 11: "Nov", 12: "Dec"}
	fmt.Println(cap(month))
	summer := month[6:9]
	Q2 := month[4:7]
	fmt.Println(cap(Q2))
	fmt.Println(len(Q2))

	fmt.Println(cap(summer))
	fmt.Println(len(summer))
}

The Output are

13
9
3
7
3

Month Slice has 12 elements but the cap(month) and len(month) return 13, Why?

答案1

得分: 5

首先,month 是一个数组(array),而不是切片(slice),它的类型是 [13]string。通过查看它的类型,我们可以知道它有 13 个元素(长度),与切片的类型 []string 相比。

数组和切片的索引从零开始,而不是从一开始。由于你没有在数组中指定索引为 0 的字符串值:

month := [...]string{1: "Jan", 2: "Fab", 3: "March", 4: "April", 5: "May", 6: "June", 7: "July", 8: "Aug", 9: "Sep", 10: "Oct", 11: "Nov", 12: "Dec"}

它等同于:

month := [13]string{0: "", 1: "Jan", 2: "Fab", 3: "March", 4: "April", 5: "May", 6: "June", 7: "July", 8: "Aug", 9: "Sep", 10: "Oct", 11: "Nov", 12: "Dec"}

也就是说,string零值(即空字符串)作为第一个元素提供。

请注意,我用 13 替换了 ...。省略号告诉编译器根据初始化器推断数组的长度(它是类型的一部分)。

即使你使用切片字面量而不是数组字面量作为初始化器:

month := []string{1: "Jan", 2: "Fab", 3: "March", 4: "April", 5: "May", 6: "June", 7: "July", 8: "Aug", 9: "Sep", 10: "Oct", 11: "Nov", 12: "Dec"}

(在这种情况下是切片)month 的长度仍然是 13,原因与上述相同。

英文:

First, month is an array – not a slice – and its type is [13]string. We know it has 13 elements (the length) just by looking at its type, in contrast to a slice whose type would be []string.

Array and slice indices start at zero, not at one. Since you are not specifying the string value at index 0 for the array in:

month := [...]string{1: "Jan", 2: "Fab", 3: "March", 4: "April", 5: "May", 6: "June", 7: "July", 8: "Aug", 9: "Sep", 10: "Oct", 11: "Nov", 12: "Dec"}

It is equivalent to:

month := [13]string{0: "", 1: "Jan", 2: "Fab", 3: "March", 4: "April", 5: "May", 6: "June", 7: "July", 8: "Aug", 9: "Sep", 10: "Oct", 11: "Nov", 12: "Dec"}

That is, the zero value for string (i.e., the empty string) is provided as the first element.

Note that I've replaced ... with 13. The ellipsis tells the compiler to deduce the array's length (which is part of its type) based on the initializer.

Even if you had used a slice literal instead of an array literal as the initializer:

month := []string{1: "Jan", 2: "Fab", 3: "March", 4: "April", 5: "May", 6: "June", 7: "July", 8: "Aug", 9: "Sep", 10: "Oct", 11: "Nov", 12: "Dec"}

The length of (in this case the slice) month still will be 13 for the same reason as above.

huangapple
  • 本文由 发表于 2023年1月17日 23:15:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/75148502.html
匿名

发表评论

匿名网友

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

确定