Объявление цикла ForClause и циклов с условием

Объявление цикла ForClause и циклов с условием


Чтобы учесть самые разные случаи использования, существует три разных способа создания циклов for в Go, каждый из которых имеет свои возможности. Вы можете создать цикл for с условием, ForClause и RangeClause. В этом разделе мы расскажем, как объявлять и использовать ForClause и цикл с условием.

Давайте посмотрим, как мы можем использовать цикл for с ForClause.

Цикл ForClause определяется как цикл с инициирующим оператором, за которым следует условие и пост-оператор. Они имеют следующий синтаксис:

for [ Initial Statement ] ; [ Condition ] ; [ Post Statement ] {
    [Action]
}

Чтобы объяснить, что делают компоненты выше, давайте рассмотрим цикл for, который выполняет увеличение в указанном диапазоне значений с помощью синтаксиса ForClause:

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

Copy

Давайте разобьем этот цикл на части и рассмотрим каждую часть.

Первая часть цикла — i := 0. Это инициирующий оператор:

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

Он указывает, что мы объявляем переменную с именем i и задаем первоначальное значение 0.

Далее идет условие:

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

В этом условии мы указываем, что пока i меньше 5, цикл будет продолжать работу.

А в конце мы получаем пост-оператор:

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

В этой части мы инкрементируем значение переменной i на 1 каждый раз после каждой итерации с помощью оператора инкремента i++.

При запуске этой программы вывод выглядит следующим образом:

Output
0
1
2
3
4

Цикл отработал 5 раз. Первоначально он задает для i значение 0, а затем проверяет, является ли значение i меньше 5. Так как значение i меньше 5, цикл выполняется и функция fmt.Println(i) исполняется. После завершения цикла вызывается оператор i++, а значение i увеличивается на 1.

Примечание. Необходимо помнить, что в программировании мы обычно начинаем индексы с 0, поэтому хотя было выведено 5 чисел, они варьируются в диапазоне от 0 до 4.

Мы не обязательно должны начинать с 0 или заканчивать заданным значением. Мы можем присвоить любое значение для нашего инициирующего оператора и останавливать работу цикла на любом значении пост-оператора. Это позволяет нам создавать желаемый диапазон для работы цикла:

for i := 20; i < 25; i++ {
    fmt.Println(i)
}

Copy

Здесь итерация выполняется с 20 (включая) до 25 (не включая), поэтому вывод выглядит следующим образом:

Output
20
21
22
23
24

Также мы можем использовать наш пост-оператор для инкрементирования на различных значениях. Это аналогично шагу в других языках:

Сначала давайте воспользуемся пост-оператором с положительным значением:

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

В данном случае цикл for задан таким образом, чтобы выводить числа с 0 до 15, но с увеличением на 3, так что на экран будет выводиться только каждое 3 число:

Output
0
3
6
9
12

Также мы можем использовать отрицательное значение для аргумента пост-оператора, чтобы выполнять итерацию в обратном направлении, но при этом нам нужно будет изменить инициирующий оператор и аргументы условий:

for i := 100; i > 0; i -= 10 {
    fmt.Println(i)
}

Copy

Здесь мы зададим для i начальное значение 100, воспользуемся условием i < 0 для остановки при 0, а в пост-операторе будем уменьшать значение на 10 с помощью оператора -=. Цикл начинает работу при 100 и заканчивается при 0, а значение уменьшается на 10 при каждой итерации. Вы можете увидеть, как это происходит, в выводе:

Output
100
90
80
70
60
50
40
30
20
10

Также вы можете исключить инициирующий оператор и пост-оператор из синтаксиса for и использовать только условие. Это так называемый цикл с условием:

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

На этот раз мы объявили переменную i отдельно от цикла for в предшествующей строке кода. Цикл имеет только одно условие, которое проверяет, остается ли i менее 5. Если условие возвращает true, цикл будет продолжаться.

Иногда вы можете не знать количество итераций, которое вам потребуется для выполнения определенной задачи. В этом случае вы можете пропустить все операторы и использовать ключевое слово break для прекращения цикла:

for {
    if someCondition {
        break
    }
    // do action here
}

Подобный пример можно использовать, если мы будем выполнять чтение из структуры с неопределенным размером, например, из буффера, и мы не знаем, когда чтение будет завершено:

buffer.go

package main

import (
    "bytes"
    "fmt"
    "io"
)

func main() {
    buf := bytes.NewBufferString("one\ntwo\nthree\nfour\n")

    for {
        line, err := buf.ReadString('\n')
        if err != nil {
            if err == io.EOF {

                fmt.Print(line)
                break
            }
            fmt.Println(err)
            break
        }
        fmt.Print(line)
    }
}

Copy

В предыдущем коде buf :=bytes.NewBufferString("one\ntwo\nthree\nfour\n") объявляет буфер с некоторыми данными. Поскольку мы не знаем, когда буфер завершит чтение, мы создадим цикл for без условия. Внутри цикла for мы используем строку line, err := buf.ReadString('\n') для считывания строки из буфера и проверки на наличие ошибок при чтении из буфера. Если произошла ошибка, мы устраняем ее и используем ключевое слово break для выхода из цикла. С этими точками break вам не нужно добавлять условие, чтобы остановить цикл.


Report Page