Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extend slice length on the left

Tags:

I just started going through gotour, and encountered a question regarding slice defaults chapter.

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

I can extend the length of slice on the right by picking an index greater than or equal to previous slice length. e.g. s[:4] so I can reach entry 11. But when I uses[-1:] to extend on the left and reach entry 2, compiler gives me error invalid slice index -1 (index must be non-negative). Is it possible to extend the slice length on the left to reach entry 2 after s=s[1:4] executed?

like image 678
Pay C. Avatar asked Oct 08 '17 07:10

Pay C.


People also ask

How can I increase my slice capacity?

"Extending" a slice to its capacity is simply a slice expression, and specify the capacity as the high index. The high index does not need to be less than the length. The restriction is: For arrays or strings, the indices are in range if 0 <= low <= high <= len(a) , otherwise they are out of range.

What is the length of the slice?

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) .

How do you measure the length of a slice in Go?

To get length of slice in Go programming, call len() function and pass the slice as argument to it. len() function returns an integer, the length of slice. The function returns an integer value, representing the length of given slice.


1 Answers

Firstly, to answer your question, no it's not possible to use negative indices or access that data except by keeping a copy of the original slice.

However this is an interesting question, as there is an inconsistency here that you've pointed out, which is probably more what you're asking about. If you start with a slice as here:

a := []int{2, 3, 5, 7, 11, 13} fmt.Println(a,len(a),cap(a))  

[2 3 5 7 11 13] 6 6

And take a slice of just the middle

b := a[1:2] fmt.Println(b,len(b),cap(b))  

[3] 1 5

You are not allowed to access indexes in the original data past that slice len, as you'd expect:

fmt.Println(b[3])  

panic: runtime error: index out of range

You are not allowed to reslice to include that data again from before the start index:

d := b[-1:] 

invalid slice index -1 (index must be non-negative)

But you are allowed to reslice to include that data again after the len up to cap, which is a little odd:

// This is beyond the length of b, you can't index those,  // but you can access them by reslicing  c := b[:5] 

[3 5 7 11 13] 5 5

This is a bit inconsistent as most other operations on slice data are bounded by the offset into the data and the len, not the cap and original data length. However, this is explicitly stated in the spec and is probably just an artefact of how slices represent the view onto the original array rather than an intentional design decision to provide access to that data. It might be nice if you could get back to the original storage, since it is still in memory, but it seems you can only see the end of the array up to cap, not the start after you have sliced once. From the spec about limits on slicing indexes:

For arrays or strings, the indices are in range if 0 <= low <= high <= len(a), otherwise they are out of range. For slices, the upper index bound is the slice capacity cap(a) rather than the length. A constant index must be non-negative and representable by a value of type int; for arrays or constant strings, constant indices must also be in range. If both indices are constant, they must satisfy low <= high. If the indices are out of range at run time, a run-time panic occurs.

It would probably be better to be safe and use the original slice to create different views on the data, rather than relying on this behaviour.

like image 118
Kenny Grant Avatar answered Sep 17 '22 17:09

Kenny Grant