-
Notifications
You must be signed in to change notification settings - Fork 0
create slice from nothing
Let's create an array of integers with 10 elements:
array := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
We create a slice of integers with 3 elements from the above array:
slice1 := array[0:3]
Let's see how the slice and the array look like:
fmt.Printf("Array: %#v", array)
fmt.Printf("Slice: %#v", slice1)
// output:
// Array: [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
// Slice: []int{1, 2, 3}
Now, let's push our luck and try to access an index that doesn't exist in the slice, for example, 5:
fmt.Printf("Slice[4]: %#v", slice[5])
// output:
// panic: runtime error: index out of range [5] with length 3
In other words, the slice doesn't contain index 5, and that's why we received the error above. It seems logical.
Now, let's create a new slice that includes the elements from index 1 up to an index we're certain doesn't exist in the slice, which is index 5. Care to guess what will happen?
Let's see:
slice2 := slice[1:6]
fmt.Printf("Slice2: %#v", slice2)
// output:
// Slice2: []int{2, 3, 4, 5, 6}
What happened? Surprise: slice2 contains the element from index 1 of slice1, and the elements from index 2, 3, 4, 5 of array (which were not present in the initial slice).
If you don't believe me, let's see what happens if we modify the element at index 2 in slice2:
slice2[2] = 100 // previously the value was 4
fmt.Printf("Slice2: %#v", slice2)
fmt.Printf("Array: %#v", array)
// output:
// Slice2: []int{2, 3, 100, 5, 6}
// Array: [10]int{1, 2, 100, 4, 5, 6, 7, 8, 9, 10}
slice2 contains the element at index 2 from array, not from slice1 as you might have expected.
Remember: When we create a slice from another slice or array, beyond the number of elements we specify for the new slice, we obtain the upper limit of the new slice from the initial array. In this case, slice1 contains 3 elements but has the capacity of the initial array, which is 10 elements. That's why we were able to create slice2 with 5 elements, even though slice1 only contains 3 elements.
fmt.Printf("Slice1 len: %d", len(slice1), cap(slice1))
// output:
// Slice1 len: 3, cap: 10
It is clearly visible that the capacity of slice1 is 10 elements.
I have used this effect to create a package that checks if two slices have the same underlying array. You can find it at https://github.com/doITmagic/go-snippets/tree/main/slices.
This package have a limitation, if the slice is creating from an array or slice using ":" operator, in case it is use the second ":" time the operator like initialSlice[1:4:3] (where 3 is the capacity) the function will return false because the capacity of the slice is different from the capacity of the initial slice or array
- logger package : simply concurrent logger made using sync and io packages
- hashtable package : a hashtable made in golang