こんなんどこで学ぶんや!ってなったやつ。
再現コード
実際に遭遇したのとは違うけど、
fn main() {
let max = u8::MAX;
println!("MAX: {max} | MAX+1: {}", max + 1);
}
こういうコードを用意し、
cargo run
した場合、
thread 'main' panicked at src/main.rs:3:40:
attempt to add with overflow
と表示される。
考えてみれば、JSと違って扱える型やその最大値が決まってるならば、それを踏み越えたときに問題になるのはまあわかる。
が、
cargo run -r
した場合は、
MAX: 255 | MAX+1: 0
なんとpanicしない!
overflow-checks
https://doc.rust-lang.org/reference/expressions/operator-expr.html#overflow https://doc.rust-lang.org/cargo/reference/profiles.html#overflow-checks
リリースビルドではこの設定がOFFになってるらしく、有効にする場合は、
[profile.release]
overflow-checks = true
これをCargo.toml
に追記するか、同等のフラグを渡す。
そもそも
いやいやパニックは困る・・・という場合。
match max.checked_add(1) {
Some(p1) => println!("MAX: {max} | MAX+1: {p1}"),
None => println!("MAX: {max} | MAX+1: Overflow"),
}
というように、安全に計算できるやつがある。
checked_add()
checked_sub()
checked_mul()
- etc…
もちろんu8
だけじゃなくあらゆる数値型で使えるようだった。
https://doc.rust-lang.org/1.80.1/src/core/num/uint_macros.rs.html#457
ほかにも
溢れたときの挙動をどうしたいかによって、他にも派生形が使える。
saturating_*
wrapping_*
overflowing_*
勉強になった。