Перейти до основного вмісту
Модуль 4 · Урок 2 із 517/50 у курсі~15 min
Модульні уроки (2/5)

Зрізи: ідіоматична структура

Зрізок — це структура даних, яка найчастіше використовується в Go: динамічний перегляд над базовим масивом. Синтаксис: []T. На відміну від масивів, довжина не є частиною типу, і ви можете збільшити його за допомогою append.

Анатомія зрізу

Внутрішньо зріз є структурою з трьох полів:

  • вказівник на перший елемент у базовому масиві
  • довжина (len): кількість видимих елементів
  • ємність (cap): елементи, доступні на початку перегляду до кінця основного масиву
Go
s := []int{10, 20, 30}
fmt.Println(len(s), cap(s)) // 3 3

Створення

Go
a := []int{1, 2, 3}          // literal
b := make([]int, 3)          // [0 0 0]   len=3 cap=3
c := make([]int, 3, 10)      // len=3 cap=10 (reserved)
var d []int                  // nil slice: len=0 cap=0, still usable with append

append: завжди призначати результат

append додає елементи та повертає новий фрагмент (потенційно виділення нового масиву, якщо ємності недостатньо):

Go
s := []int{1, 2, 3}
s = append(s, 4)              // [1 2 3 4]
s = append(s, 5, 6, 7)        // append multiple elements
s = append(s, altra...)       // concatenate another slice (spread)

Вираз фрагмента s[a:b]

Витягує підрозділ від a (включно) до b (виключно):

Go
s := []int{10, 20, 30, 40, 50}
sub := s[1:4]              // [20 30 40]
inizio := s[:2]            // [10 20]
fine := s[3:]              // [40 50]
intera := s[:]             // [10 20 30 40 50]

Підрозділи поділяють базовий масив з оригінальним фрагментом: мутації через sub[i] = ... також видно в s.

Підводний камінь: спільний доступ до масиву

Go
s := []int{1, 2, 3, 4}
sub := s[0:2]
sub[0] = 99
fmt.Println(s)             // [99 2 3 4] — modified!

Щоб отримати незалежну копію, використовуйте copy або append:

Go
out := make([]int, len(sub))
copy(out, sub)

Спробуйте

вправи#go.m4.l2.e1
Спроби: 0Завантаження…

Створіть фрагмент s за допомогою [1, 2, 3] і використовуйте append, щоб додати 4.

Завантаження редактора…
Показати підказку

ЗАВЖДИ призначайте результат додавання назад до `s`.

Рішення доступне після 3 спроб

вправи#go.m4.l2.e2
Спроби: 0Завантаження…

Використовуйте вираз зрізу, щоб витягти елементи з індексу 1 включно до 3 винятково (тобто [20, 30]).

Завантаження редактора…
Показати підказку

Синтаксис: `s[початок:кінець]`, `початок` включно, `кінець` винятково.

Рішення доступне після 3 спроб

Quiz#go.m4.l2.e3
Готовий

Що з цього НЕПРАВИЛЬНО написати?

Go
s := []int{1, 2, 3}
// (a) s = append(s, 4)
// (b) append(s, 4)
Варіанти відповідей

Підведення підсумків

  • []T: динамічний перегляд масиву; потрійний (ptr, len, cap).
  • make([]T, len, cap) для попереднього розподілу; var s []T для корисного нульового фрагмента.
  • s = append(s, ...): ЗАВЖДИ призначати результат.
  • s[a:b] спільно використовує базовий масив: copy(...) для незалежних копій.
  • Зріз nil = OK для читання/діапазону/додавання; дуже відрізняється від нульової карти.