This seems very strange, With in a loop there is a local variable slice
with new value assigned for each loop and I'm appending that slice to a global sliceWrappers
. After the loop completes, all values inside the global slice contains only reference to the last value set on that local slice variable.
Code:
package main
import (
"fmt"
"strconv"
)
func main() {
var sliceWrappers [][]string
initialSlice := append([]string{}, "hi")
initialSlice = append(initialSlice, "there")
// Remove this line and it works fine
initialSlice = append(initialSlice, "I'm")
for i := 0; i < 2; i++ {
slice := append(initialSlice, strconv.Itoa(i))
fmt.Printf("Slice Value : %+v, Initial Value : %+v\n", slice, initialSlice)
sliceWrappers = append(sliceWrappers, slice)
}
for _, sliceWrapper := range sliceWrappers {
fmt.Printf("%+v\n", sliceWrapper)
}
}
Actual Output:
Slice Value : [hi there I'm 0], Initial Value : [hi there I'm]
Slice Value : [hi there I'm 1], Initial Value : [hi there I'm]
[hi there I'm 1]
[hi there I'm 1]
Expected Output:
Slice Value : [hi there I'm 0], Initial Value : [hi there I'm]
Slice Value : [hi there I'm 1], Initial Value : [hi there I'm]
[hi there I'm 0] <------ This is not happening
[hi there I'm 1]
If I Remove initialSlice = append(initialSlice, "I'm")
line, then it works perfectly.
Slice Value : [hi there 0], Initial Value : [hi there]
Slice Value : [hi there 1], Initial Value : [hi there]
[hi there 0] <------ Works Perfectly
[hi there 1]
I Believe this has something to do with the append
The append built-in function appends elements to the end of a slice. If it has sufficient capacity, the destination is resliced to accommodate the new elements.
If the above condition was responsible for it, then shouldn't value of initialSlice
which was printed inside the loop also be same as slice
?
Playground - https://play.golang.org/p/b3SDGoA2Lzv
PS : I unfortunately wrote test cases for my code with just 3 levels nesting and it passed fine. I now have to take care of copy for slices inside loops.