Показаны сообщения с ярлыком for утверждения (for statements) в Go. Показать все сообщения
Показаны сообщения с ярлыком for утверждения (for statements) в Go. Показать все сообщения

понедельник, 25 мая 2020 г.

Индекс вне диапазона

Почему происходит сбой этой программы?

a := []int{1, 2, 3}
for i := 1; i <= len(a); i++ {
    fmt.Println(a[i])
}

panic: runtime error: index out of range

Ответ

В последней итерации i равен len(a), которая находится за пределами a.

Массивы, срезы и строки индексируются, начиная с нуля, поэтому значения a находятся в a[0], a[1], a[2], …, a[len(a)-1].

Вместо этого проходите цикл от 0 до len(a)-1.

for i := 0; i < len(a); i++ {
    fmt.Println(a[i])
}

Или, еще лучше, используйте range.

for _, n := range a {
    fmt.Println(n)
}


Читайте также:


вторник, 25 февраля 2020 г.

Пять базовых паттернов использования for циклов

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

Трехкомпонентная цикл

Эта версия for цикла в Go работает так же, как в C или Java.

sum := 0
for i := 1; i < 5; i++ {
    sum += i
}
fmt.Println(sum) // 10 (1+2+3+4)

  1. Выполняется инициализирующее утверждение, i := 1
  2. Вычисляется условие, i < 5
    • Если true, тело цикла выполняется,
    • в противном случае цикл завершен.
  3. Выполняется постутверждение i++
  4. Вернуться к шагу 2.

Область видимости i ограничена циклом.

While цикл

Если вы пропустите инициализирующее и постутверждение, вы получите цикл while.

n := 1
for n < 5 {
    n *= 2
}
fmt.Println(n) // 8 (1*2*2*2)

  1. Вычисляется условие, i < 5
    • Если true, тело цикла выполняется,
    • в противном случае цикл завершен.
  2. Вернуться к шагу 1.

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

Если вы пропустите условие, вы получите бесконечный цикл.

sum := 0
for {
    sum++ // повторяется бесконечно
}
fmt.Println(sum) // никогда не будет выполнено

For-each range цикл

Прохождение в цикле по элементам в срезах, массивах, картах, каналах или строках часто лучше сделать с помощью range цикла.

strings := []string{"hello", "world"}
for i, s := range strings {
    fmt.Println(i, s)
}

Вывод:

0 hello
1 world

Выход из цикла

Ключевые слова break и continue работают так же, как и в C и Java.

sum := 0
for i := 1; i < 5; i++ {
    if i%2 != 0 { // пропустить нечетные числа
        continue
    }
    sum += i
}
fmt.Println(sum) // 6 (2+4)

  • Оператор continue начинает следующую итерацию самого внутреннего цикла for, выполнив свое постутверждение (i++).
  • Оператор break покидает самое внутреннее for, switch, select утверждение.

Читайте также:


среда, 19 июня 2019 г.

Спецификация Go: for утверждения (for statements)

Утверждение "for" определяет повторное выполнение блока. Существует три формы: итерация может управляться единственным условием, "for" условием, "range" условием.

ForStmt = "for" [ Condition | ForClause | RangeClause ] Block .
Condition = Expression .

for утверждения с единственным условием

В своей простейшей форме "for" утверждение определяет повторное выполнение блока, пока булево условие оценивается как true. Условие оценивается перед каждой итерацией. Если условие отсутствует, оно эквивалентно логическому значению true.

for a < b {
    a *= 2
}

for утверждения с "for" условием

Утверждение "for" с ForClause также контролируется его условием, но дополнительно оно может указывать утверждения init и post, такие как утверждения присваивания, инкремента или декремента. Утверждение init может быть кратким объявлением переменной, но оператор post не должен. Переменные, объявленные утверждением init, повторно используются в каждой итерации.

ForClause = [ InitStmt ] ";" [ Condition ] ";" [ PostStmt ] .
InitStmt = SimpleStmt .
PostStmt = SimpleStmt .

for i := 0; i < 10; i++ {
    f(i)
}

Если не пусто, утверждение init выполняется один раз перед вычислением условия для первой итерации; оператор post выполняется после каждого выполнения блока (и только если блок был выполнен). Любой элемент ForClause может быть пустым, но точка с запятой обязательна, если только нет условия. Если условие отсутствует, оно эквивалентно логическому значению true.

for cond { S() }  то же самое что и  for ; cond ; { S() }
for      { S() }  то же самое что и  for true     { S() }


Читайте также: