Consider the following code:
let mut val : u8 = 125;
let deltas : [i8; 4] = [5, -5, 5, 5];
let delta = select_current_delta(deltas);
val += delta;
This seems simple. I want to either increase or decrease a byte value based on some criteria (and I have a way to prevent overflow of a u8
value).
This, of course, does not compile:
> rustc lala.rs
lala.rs:7:12: 7:17 error: mismatched types:
expected `u8`,
found `i8`
(expected u8,
found i8) [E0308]
lala.rs:7 val += delta;
^~~~~
Duh! Mixing signed and unsigned types seems to be forbidden in Rust. How about this?
val = (val as i8 + delta) as u8;
This compiles, but when I try to run it...
> ./lala
thread '<main>' panicked at 'arithmetic operation overflowed', lala.rs:7
Yeah, i8
's max value is 125, adding 5 will overflow, even though the value is perfectly fine for u8
.
I was able come up with two solutions that work:
val = (val as i16 + delta as i16) as u8;
// or
if delta < 0 { val -= (-delta) as u8 }
else { val += delta as u8}
Neither of those seem elegant to me. Is there an idiomatic way to add a u8 to a i8?
Is there an idiomatic way to add a
u8
to ai8
?
The problem of adding a u8
to a i8
(with +
) is: what type should the result be? Neither u8
or i8
is better, and using i16
while correct would probably be surprising.
Thus, for now, mixed-integrals operands are not supported. The idiomatic way is to cast both operands to a common type, which will also be the type of the result. This is already what you are doing.
But, what of
u8 += i8
?
Unfortunately, at the moment, this is sugar for u8 = u8 + i8
and therefore has all the limitations of +
even though the result type would not be an issue.
As all annoying limitations of Rust, there's a RFC for it! This is PR #953: Overloaded Assignment Operations. This RFC is in final comment period so a decision is expected soon, and hopefully this means that it will be accepted and Rust will gain support for mixed-integrals assignment operations.
As a personal preference, for now, I would go for:
val = (val as i16 + delta as i16) as u8;
which avoids the branch.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With