Spec: Целочисленное переполнение:
Для целых значений без знака операции +, -, * и << вычисляются по модулю 2 <sup>n , где n - ширина в битах целого числа без знака тип. Грубо говоря, эти целочисленные операции без знака отбрасывают старшие биты при переполнении, и программы могут полагаться на "циклический переход" .
Для целых чисел со знаком операции +, -, *, / и << могут юридически переполняться, и результирующее значение существует и детерминировано определяется целочисленным представлением со знаком, операцией и ее операндами. <strong>Переполнение не вызывает паники во время выполнения . Компилятор может не оптимизировать код в предположении, что переполнение не происходит. Например, он может не предполагать, что x < x + 1
всегда верно.
Как указано выше, переполнение существует и не вызывает паники во время выполнения.
Но нужно соблюдать осторожность, как если бы у вас было константных выражений , поскольку они имеют произвольную точность, если результат должен быть преобразован с фиксированной точностью, если он не вписывается в действительный целевой тип диапазон, это приводит к ошибке времени компиляции.
Например:
const maxuint64 = 0xffffffffffffffff
var key uint64 = maxuint64 * maxuint64
fmt.Println(key)
Вышеуказанные выходы:
constant 340282366920938463426481119284349108225 overflows uint64
maxuint64 * maxuint64
- это константное выражение, которое вычисляется правильно (его значение равно 340282366920938463426481119284349108225
), но когда это значение должно быть присвоено переменной key
типа uint64
, оно приводит к времени компиляции ошибка, потому что это значение не может быть представлено значением типа uint64
. Но это не паника во время выполнения.
Смотрите похожие вопросы:
Golang: целевое переполнение int
Отличается ли оценка компилятора Go для константного выражения и другого выражения
Как сохранить большой float64 в строке без переполнения?
Правильный способ приведения uint16 к int16 в Go