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)