понимание длины, емкости и «фантомных элементов» в срезах

В чем дело?

Представьте, что у вас есть корзина с 10 яблоками. Вы берете 5 таких яблок и бросаете их в корзину поменьше. А теперь самое странное: как положить 7 яблок в третью корзину, если во второй корзине у вас было только 5 яблок? Звучит невозможно, правда? Но в Go это вполне осуществимо. Давайте разгадаем этот трюк.

Начальная корзина

Во-первых, давайте создадим нашу большую корзину яблок или исходный массив в Go.

// Our initial basket with 🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎 apples (an array)
firstBasketOfApples := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

Вторая корзина

Далее берем 5 яблок из нашей большой корзины и кладем их во вторую, меньшую корзину. В Го эту вторую корзину мы называем «срезом».

//second basket with 🍎🍎🍎🍎🍎 apples from first basket (a slice)
 secondBasketOfApples := firstBasketOfApples[:5]
 fmt.Printf("secondBasketOfApples it has %d elements and components: %v \n", len(secondBasketOfApples), secondBasketOfApples)
//Output:
//       secondBasketOfApples it has 5 elements and components: [1 2 3 4 5]

Третья корзина и 🪄✨

Теперь о волшебном трюке! Из этой меньшей корзины с 5 яблоками нам удалось создать третью корзину с 7 яблоками.

// The magical act: Create a new slice holding 🍎🍎🍎🍎🍎🍎🍎 
// using only the 🍎🍎🍎🍎🍎 secondBasketOfApples
thirdBasketOfApples := secondBasketOfApples[0:7]
fmt.Printf("thirdBasketOfApples it has %d elements and components: %v \n", len(thirdBasketOfApples), thirdBasketOfApples)
//Output:
//      thirdBasketOfApples it has 7 elements and components: [1 2 3 4 5 6 7] 

Раскрытие волшебства: анатомия среза

Чтобы понять, как работает эта «магия», давайте посмотрим, что представляет собой срез в Go. Срез состоит из трех компонентов:

  1. Указатель — на первый элемент базового массива.
  2. Длина — количество элементов в срезе.
  3. Емкость —…