<aside> 💡

Це переклад статті **Ranging over functions in Go 1.23** від Eli Bendersky

</aside>


Go 1.23 поставляється з новою важливою фічею: функціями діапазону (також відомими як «ітератори»). Ця функція добре описана в офіційній публікації блогу Go за серпень.

Ця стаття є переписаною версією моєї попередньої публікації, яка описувала цю фічу, коли вона була ще в попередній версії. Тоді функція дещо відрізнялася, і я хочу, щоб ця стаття відображала прийнятий та остаточний стан речей. Повний код для цієї статті доступний у супровідному репозиторії.

Передумови - оригінальні оператори for-range

Усі програмісти Go знають і люблять старий добрий цикл for ... := range; чи то перебір елементів зрізу, рун у рядку, чи пар ключ/значення у мапі - це універсальний інструмент, без якого не обходиться майже жодна програма.

for i, elem := range mySlice {
    // використання індексу i чи елемента elem в будь-який спосіб
}

Проте досі оператори for-range були обмежені відносно невеликою кількістю конструкцій Go: масивами, зрізами, рядками, мапами та каналами.

Перебір int

Перше доповнення, зроблене в пропозиції, це перебір цілих чисел. Ось простий приклад того, як це виглядає:

for i := range 5 {
  fmt.Println(i)
}

Цей код повністю еквівалентний:

for i := 0; i < 5; i++ {
  fmt.Println(i)
}

І робить те саме: виводить числа 0,1,2,3,4 - кожне на окремому рядку. Очевидно, що число для перебору не обов'язково має бути константою, а присвоєння значення перебору для кожної ітерації є необов'язковим:

for range n {
  // зробити щось
}

Конструкція вище зробить щось рівно n разів. Ось і все! Це просто зручне скорочення для дуже поширеного циклу (i := 0; i < n; i++). У пропозиції Расс зазначив, що приблизно половину трьохкомпонентних циклів for, які він спостерігав "у дикій природі", можна перетворити на цю форму "перебору по числу". Це включає бенчмарки Go, де основний цикл можна перетворити на:

for range b.N {
  // виконати код для бенчмарку
}

Перебір чисел простий і зрозумілий, тому не буду витрачати на це багато часу. Перейдемо до більш значної зміни - перебору функцій.

Перебір функцій - мотивація

Після додавання дженериків у Go у версії 1.18, розробники почали писати дженерик контейнери або Абстрактні Структури Даних; дженерики дозволяють програмістам ефективно та зручно відокремлювати структуру даних від типів, які вона зберігає (порівняно зі старим способом використання порожніх інтерфейсів).