# Conversions, pt. 1 We've repeated over and over again that Rust won't perform implicit type conversions for integers.\ How do you perform _explicit_ conversions then? ## `as` You can use the `as` operator to convert between integer types.\ `as` conversions are **infallible**. For example: ```rust let a: u32 = 10; // Cast `a` into the `u64` type let b = a as u64; // You can use `_` as the target type // if it can be correctly inferred // by the compiler. For example: let c: u64 = a as _; ``` The semantics of this conversion are what you expect: all `u32` values are valid `u64` values. ### Truncation Things get more interesting if we go in the opposite direction: ```rust // A number that's too big // to fit into a `u8` let a: u16 = 255 + 1; let b = a as u8; ``` This program will run without issues, because `as` conversions are infallible. But what is the value of `b`? When going from a larger integer type to a smaller, the Rust compiler will perform a **truncation**. To understand what happens, let's start by looking at how `256u16` is represented in memory, as a sequence of bits: ```text 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 | | | +---------------+---------------+ First 8 bits Last 8 bits ``` When converting to a `u8`, the Rust compiler will keep the last 8 bits of a `u16` memory representation: ```text 0 0 0 0 0 0 0 0 | | +---------------+ Last 8 bits ``` Hence `256 as u8` is equal to `0`. That's... not ideal, in most scenarios.\ In fact, the Rust compiler will actively try to stop you if it sees you trying to cast a literal value which will result in a truncation: ```text error: literal out of range for `i8` | 4 | let a = 255 as i8; | ^^^ | = note: the literal `255` does not fit into the type `i8` whose range is `-128..=127` = help: consider using the type `u8` instead = note: `#[deny(overflowing_literals)]` on by default ``` ### Recommendation As a rule of thumb, be quite careful with `as` casting.\ Use it _exclusively_ for going from a smaller type to a larger type. To convert from a larger to smaller integer type, rely on the [_fallible_ conversion machinery](../05_ticket_v2/13_try_from.md) that we'll explore later in the course. ### Limitations Surprising behaviour is not the only downside of `as` casting. It is also fairly limited: you can only rely on `as` casting for primitive types and a few other special cases.\ When working with composite types, you'll have to rely on different conversion mechanisms ([fallible](../05_ticket_v2/13_try_from.md) and [infallible](../04_traits/09_from.md)), which we'll explore later on. ## Further reading - Check out [Rust's official reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#numeric-cast) to learn the precise behaviour of `as` casting for each source/target combination, as well as the exhaustive list of allowed conversions.