Підручник Golang For Loop [With Examples]

Розберіться повністю з циклами for в Golang, переглянувши кілька практичних прикладів кодування.

Останнім часом мови програмування, такі як Rust, Golang та TypeScript, набувають значної популярності серед розробників. Якщо вас цікавить розробка бекенду та DevOps, вивчення Golang може стати чудовим вибором!

Якщо ви тільки починаєте свій шлях у програмуванні, розуміння концепції циклів є однією з перших необхідних навичок.

У Golang доступна лише одна конструкція циклу – цикл for. Ми розглянемо його детально, а також дізнаємося, як за допомогою циклу for імітувати інші типи циклів.

Отже, почнемо!

Синтаксис циклу for у Golang

У Golang цикл for створюється за допомогою наступного синтаксису:

for initialization; condition; update {
    // виконуваний код
  }

Де:

  • initialization – це ініціалізація змінної циклу.
  • condition – умова, яка визначає, чи виконуватиметься тіло циклу. Операції всередині циклу виконуються, поки ця умова є істинною. Як тільки умова стає хибною, виконання програми переходить за межі циклу.
  • update – оновлення змінної циклу (зазвичай інкремент або декремент).

💡 Зверніть увагу, наскільки це схоже на цикл for в C, але без круглих дужок.

Ось як виглядає потік управління в циклах for Golang:

Настав час написати кілька прикладів! ⏰ Ви можете скористатися локальною інсталяцією Golang або запустити приклади на Go Playground.

Приклади використання циклу for у Golang

Застосуємо вивчений синтаксис для створення нашого першого циклу for. Нижче наведено простий цикл for, що виводить числа від 1 до 5 з кроком 1.

package main

import "fmt"

func main() {
    fmt.Println("Цикл for:")
    num := 5
    for i := 1; i <= num; i++ {
        fmt.Println(i)
    }
}

Тут ми ініціалізуємо змінну циклу i зі значенням 1, встановлюємо умову i <= 5 та збільшуємо змінну на 1 після кожної ітерації. Ось результат:

//Вивід
Цикл for:
1
2
3
4
5

Спробуємо ще один цикл for. Цей цикл починає відлік з 5 до 1; виконання триває, поки змінна циклу не стане меншою або рівною 1. Після кожної ітерації значення змінної циклу зменшується на одиницю.

package main

import "fmt"

func main() {
    fmt.Println("Цикл for:")
    num := 5
    for i := num; i >= 1; i-- {
        fmt.Println(i)
    }
}

Очікуваний результат:

//Вивід
Цикл for:
5
4
3
2
1

Область видимості змінної циклу

Змінна циклу має область видимості, обмежену блоком циклу for, і вона недоступна поза його межами.

Щоб це перевірити, спробуємо звернутися до значення змінної циклу i поза циклом:

package main

import "fmt"

func main() {
    fmt.Println("Цикл for:")
    num := 5
    for i := 1; i <= num; i++ {
        fmt.Println(i)
    }
    fmt.Println(i)

}

Як і передбачалося, ми отримали помилку про те, що i не визначено (її область видимості обмежена циклом for):

// Вивід
./prog.go:11:14: undefined: i

Нескінченний цикл for в Golang

Чи можна створити нескінченні цикли for у Go? Так, це можливо!

Зверніть увагу на потік управління циклом for:

  • Тіло циклу виконується доти, доки умова оцінюється як істина.
  • Якщо умова стає хибною, управління передається за межі циклу.
  • Таким чином, якщо умова ніколи не стає хибною (тобто завжди істинна), ми отримуємо нескінченний цикл.

Ви можете використовувати цикл for без ініціалізації, умови та оновлення – це не призведе до синтаксичної помилки. Таким чином, ви можете зробити цикл нескінченним, використовуючи таку конструкцію:

package main

import "fmt"

func main() {
    for {
        fmt.Println("працює...")
    }
}
//Вивід
працює...
працює...
працює...
працює...
працює...
//і так до нескінченності!

У наступному прикладі ми присвоюємо змінній num значення 5. Умова циклу — num > 0. Цикл виконуватиметься, поки num більше за 0.

package main

import "fmt"

func main() {
    num := 5
    for num > 0 {
        fmt.Println(num)
    }
}

Оскільки значення num ніколи не змінюється, умова завжди оцінюється як істинна, і цикл працює нескінченно!

//Вивід
5
5
5
5
5
5
//і так до нескінченності!

Оскільки у Golang є лише цикл for, ми можемо спробувати імітувати цикли while та do-while за допомогою циклів for. Давайте розглянемо, як це зробити!

Імітація циклу while за допомогою циклу for

Цикл while зазвичай має такий формат:

// ініціалізація змінної циклу
while (умова){
    // код, який потрібно виконати
    // оновлення змінної циклу
}

Згадайте наш перший нескінченний цикл for: ми використовували цикл for без ініціалізації, умови та оновлення.

for {
    // найпростіший нескінченний цикл
}

Отже, ми можемо змінити цикл for, щоб він містив лише умову (в наступному форматі), щоб імітувати цикл while:

// ініціалізація змінної циклу
for умова {
    // код, який потрібно виконати
    // оновлення змінної циклу
}

Ось еквівалент циклу while для першого циклу for, який ми написали:

package main

import "fmt"

func main() {
    fmt.Println("Імітація циклу while")
    num := 5
    for num > 0 {
        fmt.Println(num)
        num--
    }
}
//Вивід
Імітація циклу while
5
4
3
2
1

Імітація циклу do-while за допомогою циклу for

Якщо ви використовували такі мови програмування як C, ви знаєте, що цикл do-while має такий формат:

// ініціалізація змінної циклу
do {
    // код, який потрібно виконати
    // оновлення змінної циклу
} while(умова);

Ключова різниця між циклами while та do-while полягає в тому, що while перевіряє умову перед виконанням тіла циклу. Натомість цикл do-while перевіряє умову після виконання тіла.

Таким чином, у циклі while, якщо умова є хибною, тіло циклу не виконується жодного разу. Однак у циклі do-while тіло циклу виконується принаймні один раз, навіть якщо умова є хибною.

Використовуючи ці знання, ми можемо імітувати поведінку циклу do-while:

  • Створюємо нескінченний цикл for.
  • Використовуємо умовний оператор if з відповідною умовою для виходу з циклу.

Припустимо, ви хочете написати цикл do-while, де умовою для виконання є num < 0. Тоді ви можете створити цикл for і вийти з нього, якщо num >= 0.

package main

import "fmt"

func main() {
    fmt.Println("Імітація циклу do-while")
    num := 5
    for {
        fmt.Println("цикл працює...")
        if num >= 0 {
            break
        }
    }
}

💡 Зверніть увагу, що умова виконання циклу, коли num < 0, та вихід із циклу, коли num >= 0, є еквівалентними.

Хоча умова num > 0 спочатку є хибною (num дорівнює 5), тіло циклу виконується один раз, що імітує цикл do-while.

//Вивід
Імітація циклу do-while
цикл працює...

Перебір масивів за допомогою циклу for

Використовуючи цикл for з діапазоном (range) у Golang, ви можете отримати доступ як до індексів, так і до елементів масиву. Це схоже на функцію enumerate в Python.

Тут ми створюємо масив цілих чисел numArray та перебираємо його за допомогою циклу for:

package main

import "fmt"

func main() {
    fmt.Println("Перебір масиву")
    numArray := []int{3, 7, 0, 10, 8, 9}
    for idx, num := range numArray {
        fmt.Println("Індекс", idx, ": ", num)
    }
}

Як бачимо, ми можемо одночасно отримати доступ як до індексу, так і до значення елемента за цим індексом:

//Вивід
Перебір масиву
Індекс 0 :  3
Індекс 1 :  7
Індекс 2 :  0
Індекс 3 :  10
Індекс 4 :  8
Індекс 5 :  9

Використання defer у циклі for в Golang

У Golang ви можете використовувати ключове слово defer для відкладання викликів функцій.

Хоча зазвичай це використовується для очищення ресурсів або обробки помилок, це корисний приклад для розуміння роботи defer у циклі for. Давайте подивимося, що відбувається, коли ми використовуємо defer всередині циклу for, щоб відкласти виклики функції Println().

package main

import "fmt"

func main() {
    fmt.Println("Цикл for:")
    num := 5
    for i := 1; i <= num; i++ {
        defer fmt.Println(i)
    }
}

💬 Коли виклик функції відкладено, він додається до стеку та виконується у порядку LIFO (останнім прийшов – першим пішов). Виконання відкладених викликів відбувається лише після того, як завершиться функція, у якій знаходиться оператор defer.

Отже, спочатку виконається fmt.Println(5), а останнім – fmt.Println(1):

//Вивід
Цикл for:
5
4
3
2
1

Висновок

Короткий підсумок того, що ви дізналися з цієї статті:

  • У Golang ви можете створювати цикли for з таким синтаксисом: for initialization; condition; update { //тіло циклу }.
  • Потік управління циклом for є досить простим: змінна циклу ініціалізується один раз, умова визначає, чи потрібно виконувати тіло циклу, а оновлення стосується зміни значення змінної циклу після кожної ітерації.
  • Область видимості змінної циклу обмежена тілом циклу і недоступна поза його межами.
  • Хоча Golang має лише конструкцію циклу for, ви можете імітувати поведінку циклів while та do-while за допомогою циклів for.
  • Цикл for також може використовуватися для перебору масивів та відкладання викликів функцій у тілі циклу for.

Наступним кроком розгляньте, як використовувати цикли for у Python. Вдалого навчання! 🎉