пятница, 22 мая 2020 г.

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

Почему этот цикл работает вечно?

var b byte
for b = 250; b <= 255; b++ {
    fmt.Printf("%d %c\n", b, b)
}

Ответ

После итерации b == 255 выполняется b++. Это переполненяет byte (поскольку максимальное значение для byte составляет 255) и приводит к b == 0. Следовательно, b <= 255 все еще выполняется, и цикл перезапускается с 0.

Для целочисленных значений без знака (unsigned integer) операции +, -, * и << вычисляются по модулю 2n, где n - ширина бит целого типа без знака.

Для целых чисел со знаком (signed integer) операции +, -, * и << могут легально переполняться, и результирующее значение существует и детерминировано определяется представлением целого числа со знаком, операцией и ее операндами. Исключение не возникает в результате переполнения.

Спецификация языка программирования Go: арифметические операторы

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

var b byte
for b = 250; b < 256; b++ {
    fmt.Printf("%d %c\n", b, b)
}

../main.go:2:17: constant 256 overflows byte

Одним из решений является использование более широкого типа данных, такого как int.

for i := 250; i < 256; i++ {
    fmt.Printf("%d %c\n", i, i)
}

250 ú
251 û
252 ü
253 ý
254 þ
255 ÿ

Другой вариант - поставить тест завершения в конце цикла.

for b := byte(250); ; b++ {
    fmt.Printf("%d %c\n", b, b)
    if b == 255 {
        break
    }
}

250 ú
251 û
252 ü
253 ý
254 þ
255 ÿ


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


Комментариев нет:

Отправить комментарий