Practical examples of numeric type casting (`as` vs other approaches)

I just listened to the excellent rustacean station episode 13.

There was a comment about some problems with as for type casting numeric types. (Around 28:41)

  • Do you use and see as frequently for converting between numeric types?
  • If not, how do you do these conversions? Or what is the most common way you see these converted?

For context I am volunteering on the exercism V3 track and we introduce students to numeric types and type casting early on. I'm curious about real world use of this to inform that documentation and learning experience.

Any real project examples would be great. We are heavily referencing "The Book" as well.

Typically I see conversions done using as until someone adds clippy and people switch to u64::from(...). This happened e.g. at my former job at Omnio.

1 Like

I think as and +, -, etc. have same characteristics: They are short, work for good data, but sometimes emit unintended (or silently modified) result for some input.
For example, + panics in debug build when overflow happens, but it wraps the result in release build.

In contrast, From::from() and TryFrom::try_from() are safe conversions, similar to i32::checked_add() and i32::wrapping_add() are safe and explicit.
They ensures they can always success, or force us to handle possible errors.

For conversions, I usually prefer From and TryFrom as they are more explicit and safe.
unsafe { &*(slice as *const Slice as *const AnotherSlice) } is an exception, it is well-known idiom to convert slice type to another slice type (and clippy also suggests writing as this).

2 Likes