Я портирую некоторый код Go на Rust и понял, что Rust паникует, когда происходит переполнение во время умножения, в то время как Go допускает переполнение.
Тестовый код ниже, который не вызывает переполнения, но печатает уменьшенное значение. (проверено через: https://play.golang.org/)
func main() {
fmt.Println("test\n")
var key uint64 = 15000;
key = key*2862933555777941757 + 1
fmt.Println(key)
}
Спецификация: Целочисленное переполнение:
For unsigned integer values, the operations +, -, *, and << are computed modulo 2n, where n is the bit width of the unsigned integer's type. Loosely speaking, these unsigned integer operations discard high bits upon overflow, and programs may rely on "wrap around".
For signed integers, the operations +, -, *, /, and << may legally overflow and the resulting value exists and is deterministically defined by the signed integer representation, the operation, and its operands. Overflow does not cause a run-time panic. A compiler may not optimize code under the assumption that overflow does not occur. For instance, it may not assume that
x < x + 1
is always true.
Как указано выше, переполнение существует и не вызывает панику во время выполнения.
Но нужно соблюдать осторожность, как если бы у вас был постоянные выражения, поскольку они имеют произвольную точность, если результат должен быть преобразован в фиксированную точность, где он не вписывается в допустимый диапазон целевого типа, это приводит к ошибке времени компиляции .
Например:
const maxuint64 = 0xffffffffffffffff
var key uint64 = maxuint64 * maxuint64
fmt.Println(key)
Вышеизложенное дает:
constant 340282366920938463426481119284349108225 overflows uint64
maxuint64 * maxuint64
— правильно рассчитанное константное выражение (его значение равно 340282366920938463426481119284349108225
), но когда это значение должно быть присвоено переменной key
типа uint64
, это приводит к ошибке времени компиляции, поскольку это значение не может быть представлено значением типа uint64
. Но это не паника во время выполнения.
Смотрите связанные вопросы:
Golang: специальное переполнение int
Различается ли оценка компилятора Go для константного выражения и другого выражения
Нет, как вы сами доказали, это не так. Числа усекаются на границе типа данных, в котором они хранятся.