# Slice in Go

Compare to an array with a fixed size, the slice is a dynamically-sized, flexible view into the elements of an backing array.

- Just points to other values that it stores.
- Can only contain the same type of elements.
- When a slice is created by slicing an array, that array becomes the backing array of that slice

- Pointer: point to the position of the first element of its backing array
- A nil slice does not have a backing array but it has a slice header
- Capacity: all about the length of a backing array and where a slice starts
- Empty slices usually do not allocate a new backing array, they use the same array
- Go allocates different backing arrays for each slice

- The length describes the length of a slice but a capacity describes the length of the backing array beginning from the first element of the slice
-  APPEND: when the capacity is full => append() allocates a new and a larger array (double), copy old values to the new array (costly)

   => return a new slice header that points to the newly allocated array

   => reduces the number of allocations by thinking about the future growth of the slice

- When append: append a new element to the given slice and return a new slice, does not change the given slice unless you overwrite the result of the append function back to the original slice

- Keyed slice: works like the same as a keyed array
- Use full slice expressions (using capacity when slicing) to prevent other code to append more elements to a slice's backing array.

- Make: initializes and returns a slice with the given length and capacity

   => using to prevent reallocating backing array by allocating a large enough back array

- Using make to create a new slice and then using append: will append after the length of the slice

- How to clean up memory with large array: making them lose reference to its backing array (assign it to a new empty slice)
