Go: часть 8 – циклы

Предыдущая часть – Управляющие конструкции – операторы if/else/switch/select.

У разработчика может возникнуть необходимость выполнения одного кода несколько раз.

В таком случае в программировании применяются циклы, ход выполнения которых выглядит так:

 

В Go имеется цикл типа for и вложенные циклы:

Sr.No Loop Type & Description
1 for loop
Выполняет последовательность операторов или выражений несколько раз
2 nested loops
Один или несколько циклов внутри другого

Цикл for

Ситаксис:

for [condition |  ( init; condition; increment ) | Range] {
   statement(s);
}

Выполнение цикла происходит в следующем порядке:

  • если условие (condition) указано – цикл будет выполняться, пока условие истинно (true)
  • если в цикле указывается (ициниализатор; условие; инкремент) (( init; condition; increment )) – тогда:
    • выполняется init, только один раз, при вхождении в цикл – тут вы можете объявиться и инициализировать управляющие циклом переменные
    • следующим выполняется вычисление условия (condition), и если оно true – то цикл выполняется. Если false – тело цикла пропускается, и выполнение переходит к следующему после for выражению
    • если условие было true, то после выполнения тела цикла управление переходит к началу цикла и к его оператору increment, который позволяет выполнить обновление управляющией переменной цикла
    • далее снова проверяется условие, и если оно всё ещё true, после обновления значения переменной, то цикл повторяется, а если условие становится false – то выполнение цикла прерывается, и управлеине переходит к следующему за for оператору
  • если в условии цикла используется range – то цикл будет выполнен для каждого элемента массива

Пример:

package main

import "fmt"

func main() {

    // init int b
    b := 15
    // declare int a
    var a int
    // range array
    numbers := [6]int{1, 2, 3, 5}

    /* for loop execution 
    init here: a := 0;
    condition here: a < 10;
    increment here: a++
    */
    for a := 0; a < 10; a++ {
        fmt.Printf("value of a: %d\n", a)
    }
   
    // only condition loop
    for a < b {
        a++
        fmt.Printf("value of a: %d\n", a)
     }
   

    // range loop
    for i, x:= range numbers {
        fmt.Printf("value of x = %d at %d\n", x, i)
    }
}

Результат:

[simterm]

$ go run for.go
value of a: 0
value of a: 1
value of a: 2

value of a: 14
value of a: 15
value of x = 1 at 0
value of x = 2 at 1
value of x = 3 at 2
value of x = 5 at 3
value of x = 0 at 4
value of x = 0 at 5

[/simterm]

Вложенные циклы

Go позволяет использовать циклы внутри циклов – вложенные циклы (nested loop).

Синтаксис:

for [condition |  ( init; condition; increment ) | Range] {
   for [condition |  ( init; condition; increment ) | Range] {
      statement(s);
   }
   statement(s);
}

Пример:

package main

import "fmt"

func main() {

   /* local variable definition */
   var i, j int

   for i = 2; i < 100; i++ {
      for j = 2; j <= (i/j); j++ {
         if(i%j==0) {
            break; // if factor found, not prime
         }
      }
      if(j > (i/j)) {
         
      }
   }  
}

Результат:

[simterm]

$ go run nest_loop.go
2 is prime
3 is prime
5 is prime

83 is prime
89 is prime
97 is prime

[/simterm]

Операторы контроля циклов

Операторы контроля выполнения цикла могут менять процесс выполнения цикла, и изменять его нормальную последовательность выполнения.

Список таких операторов:

Sr.No Control Statement & Description
1 break statement
It terminates a for loop or switch statement and transfers execution to the statement immediately following the for loop or switch.
2 continue statement
It causes the loop to skip the remainder of its body and immediately retest its condition prior to reiterating.
3 goto statement
It transfers control to the labeled statement.

Оператор break

Оператор break используется для:

  • когда выполнение цикла встречает оператор break – выполнение прерывается, и поток управления переходит к следующему за циклом коду
  • так же может использоваться для прерывания выполнения оператора switch

При использовании break во вложенном цикле – он прервёт выполнение текущего цикла, и передаст управление внешнему циклу.

Синтаксис:

break;

Пример:

package main

import "fmt"

func main() {

   /* local variable definition */
   var a int = 10

   /* for loop execution */
   for a < 20 {
      fmt.Printf("value of a: %d\n", a);
      a++;
      if a > 15 {
         /* once a greater then 15 - immediately terminate the loop using break statement */
         break;
      }
   }
}

Результат:

[simterm]

$ go run break.go
value of a: 10
value of a: 11
value of a: 12
value of a: 13
value of a: 14
value of a: 15

[/simterm]

Оператор continue

Оператор continue в Go работает аналогично break, но наоборот: вместо прерывания цикла он указывает на необходимость выполнить новую итерацию цикла, пропуская код после continue.

Синтаксис:

continue;

Пример:

package main

import "fmt"

func main() {

    for b := 0; b < 10; b++ {

        fmt.Printf("b = %d\n", b)
        if b == 5 {
            fmt.Printf("b = %d, so will skip to the begin\n", b)
            continue;
            fmt.Printf("this never will be printed")
        }
        fmt.Printf("rest of the loop's body\n")
    }

}

Результат:

[simterm]

$ go run contintue.go
b = 0
rest of the loop’s body
b = 1
rest of the loop’s body
b = 2
rest of the loop’s body
b = 3
rest of the loop’s body
b = 4
rest of the loop’s body
b = 5
b = 5, so will skip to the begin
b = 6
rest of the loop’s body
b = 7
rest of the loop’s body
b = 8
rest of the loop’s body
b = 9
rest of the loop’s body

[/simterm]

Оператор goto

Оператор goto в Go позволяет выполнить переключение контекста выполнения внутри одной фукнции к указанном оператору.

Учтите, что использование goto не поощряется,  так как приводит к запутанности кода.

Синтаксис:

goto label;
..
.
label: statement;

Пример:

package main

import "fmt"

func main() {

   /* local variable definition */
   var a int = 10

   LOOP: fmt.Printf("GOTO here\n")

   /* do loop execution */
   for a < 20 {
      if a == 15 {
         /* skip the iteration */
         a = a + 1
         goto LOOP
      }
      fmt.Printf("value of a: %d\n", a)
      a++
   }
}

Результат:

[simterm]

$ go run goto.go
GOTO here
value of a: 10
value of a: 11
value of a: 12
value of a: 13
value of a: 14
GOTO here
value of a: 16
value of a: 17
value of a: 18
value of a: 19

[/simterm]

Бесконечный цикл

Цикл становится бесконечным (infinite loop), если условие всегда true.

Дл создания такого цикла – достаточно не указывать никаких условий:

package main
  
import "fmt"

func main() {
   for true  {
       fmt.Printf("This loop will run forever.\n");
   }
}

Результат:

[simterm]

$ go run inf.go
This loop will run forever.
This loop will run forever.
This loop will run forever.
This loop will run forever.
This loop will run forever.
This loop will run forever.

[/simterm]

Продолжение – часть 9 – функции.