let a: u32 = 10;
let b: i32 = 100;
let c = a - b;
Even this simple operation doesn't work. u32 just can't operate with i32. But I really wonder what's the design principle behind this. I don't think u32 - i32 is more dangerous than u32 - u32. For example:
let a: u32 = 10;
let b: u32 = 100;
let c = a - b;
Does compile, but it panics at runtime. So why is Rust so paranoid about operating between different numeric types? And what's the idiomatic way to handle this, just put as everywhere?
I find it a bit crazy that even checked operations don't work on different numeric types.
let a: u32 = 10;
let b: i32 = 100;
let c = a.checked_sub(b);
This isn't unique to signed versus unsigned; Rust won't even let you add differently sized integers together:
For the specific case of adding a signed value to an unsigned one, there are functions like
checked_add_signed,overflowing_add_signed,saturating_add_signed, andwrapping_add_signed.You acknowledge in your own comment that you don't think everyone will agree on an obvious behavior, and that really is the crux of the issue. C and C++ have some awkward rules regarding integer promotion - a stray unqualified literal like
123in an expression will convert an expression to a signed integer. Rust decided to make everything explicit.