# Slices gotcha

``````s := []int{1,2,3}
t := s[:2]
t = append(t, 100)
Println(t) // {1,2,100}
Println(s) // ?
``````

If you’ve said `{1,2,100}`, good on you! You can just quickly skim through this section.

In go, an array is a contiguous piece of memory that has a fixed length. However, dynamically sized arrays are often more useful for a programmer. Go’s solution to this is slices. A slice is another datastructure that contains a pointer to the underlying array, and two values for the length and capacity.

Nothing surprising there, yet. The idiom for adding things to the dynamic array is through `append`. Suppose our original slice was

``````s := []int{1,2,3}
``````

To add another integer, we use append,

``````s = append(s, 4)
``````

We can create new slices from old ones

``````t := s[:2]
``````

It is no surprise that if we modify `t`, `s` will change as well since `t` holds the pointer to the underlying array, which is shared by `s` as well. But what happens to s when we do `t = t.append(100)`?

`s` becomes `100` of course!

When append is called, it checks if there is capacity in the underlying array. If there is, then it assigns it to that block. If there isn’t, it creates a new array, copies all the old value, and assigns the value to the correct ‘block’. In our example, there is enough capacity since our underlying array has at least capacity 3.

``````s := []int{1,2}
t := s[:2]
t = append(t, 100)
Println(t) // {1,2,100}
Println(s) // ?
``````

Here when we called append, the underlying array only has two value, so it creates a new array with length 3 and copies the old value over so t no longer holds a reference to the underlying array of s.

# For range

``````package main

import (
"fmt"
"time"
)

func main() {
s := []int{1, 2, 3, 4}
for _, value := range s {
go func() {
fmt.Println(value)
}()
}
time.Sleep(2)
}
``````

If you guess that the output is 4,4,4,4, you’re golden and you can skim through this section.

The reason for this is that value is a reference type, and on each iteration, its value points to the array address with offset given by the iteration number. When we run a goroutine that uses `value`, it gets the last iteration value.