Slices return unexpected length

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?

>Solution :

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.

Leave a Reply