3 ms·
> The trouble with explicit casting is if the code is refactored to change the underlying integer type, the explicit casts may silently truncate the integer, in
by Measter 4y ago
> The trouble with explicit casting is if the code is refactored to change the underlying integer type, the explicit casts may silently truncate the integer, introducing bugs.
That depends on how the casting is provided. For the C-style casting, or Rust's `as` casting, yes that is a problem. However, another way casting could be provided is through conversion functions that are only infallible if information isn't lost. For example, let's say we have the functions `to_u16` and `to_i16`. For an `i8` the first function could return `Option<u16>`, the second `i16`, while for a `u8` they would return `u16` and `i16`. That way, any change to the types that could cause it to now silently truncate would instead cause a compiler error because of the type mismatch.
Rust almost gets there with its `Into` and `TryInto` traits which do provide that functionality, but trying to use them in an expression causes type inference to fail, which just makes them a pain in the ass to use.
- nayuki 4y agoYou can use From and TryFrom, like u32::try_from(5i32). https://doc.rust-lang.org/std/convert/trait.From.html https://doc.rust-lang.org/std/convert/trait.From.html , https://doc.rust-lang.org/std/convert/trait.TryFrom.html https://doc.rust-lang.org/std/convert/trait.TryFrom.html
- tialaramex 4y agoAnd, notably in this context, Rust's traits are auto-implemented in a chain, so if From<Foo> for Bar, then Into<Bar> for Foo, and thus TryFrom<Foo> for Bar, and thus in turn TryInto<Bar> for Foo. This means that if first_thing used to have a non-overlapping value space so that converting it to other_thing might fail, so you wrote other_thing = first_thing.try_into().blahblahblah; ... if you later refactor and now first_thing is a subset of other_thing so that the conversion can never fail, the previous code still works fine, the try_into() call just never fails. In fact, the compiler even knows it can't fail, because its error type is now Infallible, a sum type with nothing in it, so the compiler can see this never happens, and optimise accordingly.
- WalterBright 4y agoYeah, having two different cast operations can help here. But I like the simpler approach.