2

My code snippet

package main

import "fmt"

func main() {
    s := []int{2, 3, 5, 7, 11, 13}
    fmt.Println("check 1: ",s, len(s))
    
    s = s[1:4]
    fmt.Println("check 2: ",s, len(s))

    s = s[3:5]
    fmt.Println("check 3: ",s, len(s))

    s = s[1:]
    fmt.Println("check 4: ",s, len(s))
}

Output

check 1:  [2 3 5 7 11 13] 6
check 2:  [3 5 7] 3
check 3:  [11 13] 2
check 4:  [13] 1

My Expected Output

check 1:  [2 3 5 7 11 13] 6
check 2:  [3 5 7] 3
panic: runtime error: slice bounds out of range [3:5]

s = s[1:4] - Here we updated slice variable s which now contains [3 5 7] and s = s[3:5] should give out of range error since the index 3 to 5 doesn't exist in the new value of s

Instead, why did the output print - [11 13]

vj sreenivasan
  • 1,283
  • 13
  • 15

3 Answers3

4

The slice capacity, when it is larger than the slice length, can be source of some confusion. The key idea is that a slice is a view over an array. You cannot access beyond the slice bounds, but you can re-slice it and get a new view over the underlying array.

Initially, slice length and capacity are 6.

After s = s[1:4], the slice length is 3, and capacity is 5. You can re-slice this slice to be larger than 3 elements, and still access the elements of the underlying array.

So, s[3:5] is valid, and equivalent to the [4:6] of the original slice.

Burak Serdar
  • 46,455
  • 3
  • 40
  • 59
2

This is according to golangs slice rule. Golangs slice works little bit different than other language. When a slice is taken from a slice or array it points to previous array or slice rather than copying.

                                      {2,3, 5,           7, 11, 13} //length 6
s = s[1:4] //length 3 but it points here ^ and ends here ^
           {2,3, 5,      7, 11,             13}
s = s[3:5] // it points here ^ and ends here ^

so if you did s = s[3:6] it will panic for index out of boundary.

Shahriar Ahmed
  • 502
  • 4
  • 11
1

As mentioned in golang documentations - A slice does not store any data, it just describes a section of an underlying array. A slice has both a length and a capacity. The length of a slice is the number of elements it contains. The capacity of a slice is the number of elements in the underlying array, counting from the first element in the slice. The length and capacity of a slice s can be obtained using the expressions len(s) and cap(s).

Though the length is 3 after executing s[1:4] the capacity is 5 and hence you could access s[3:5] from underlying array without index out error

Tryout the below snippet for better understanding

package main

import "fmt"

func main() {
    s := []int{2, 3, 5, 7, 11, 13}
    fmt.Printf("check 1: len=%d cap=%d %v\n", len(s), cap(s), s)

    s = s[1:4]
    fmt.Printf("check 2: len=%d cap=%d %v\n", len(s), cap(s), s)

    s = s[3:5]
    fmt.Printf("check 4: len=%d cap=%d %v\n", len(s), cap(s), s)

    s = s[1:]
    fmt.Printf("check 5: len=%d cap=%d %v\n", len(s), cap(s), s)
}

Output:

check 1: len=6 cap=6 [2 3 5 7 11 13]
check 2: len=3 cap=5 [3 5 7]
check 4: len=2 cap=2 [11 13]
check 5: len=1 cap=1 [13]
Divya S
  • 26
  • 2