Home > other >  Go's built-in range on a sub-slice of an array has incongruent behavior
Go's built-in range on a sub-slice of an array has incongruent behavior

Time:11-05

Why can't we use the built range to dictate the lower-end of given array's index, but we can specify the index's upper range?

Given a slice of int:

array := []int{4, 76, -29, 3, 9, 223, 0, -3, -44, 76, 3, 98, 62, 144}

I want to range over the slice, excluding the first two elements.

I can do this with a for-loop:

for i := 2; i < len(array); i   {
        fmt.Printf("%d ", array[i])
    }

But can't with the built-in range:

for i := range array[2:] {
        fmt.Printf("%d ", array[i])
    }

Strangely enough, i can exclude elements on the upper-range, like so:

for i := range array[:5] {
        fmt.Printf("%d ", array[i])
    }

Run it on Go Playground

Why is this?

CodePudding user response:

The expression array[2:] evaluates to new slice value. The problem is that the application assumes that the elements in the new slice have the same index as the corresponding element in array.

Here are a couple of approaches for addressing the problem.

Use the range value:

for _, v := range array[2:] {
   fmt.Printf("%d ", v)
}

Index into the new slice:

s := array[2:]
for i := ranges s {
   fmt.Printf("%d ", s[i])
}

When slicing from the end as in array[:5], the elements in the new slice have the same index as the corresponding elements in array.

CodePudding user response:

It does work, you are simply looking at the wrong slice.

The expression array[2:] is a new slice that starts from the 2'nd element of the array. The 0'th element of that slice is the 2nd element of the original slice. Do this, and you'll see:

for i,value := range array[2:] {
        fmt.Printf("%d ", value)
}

The values for i range from 0 to len(array)-2.

  • Related