Introduction
Rust does not perform implicit or automatic type coercion between numeric types, which is a deliberate design decision to avoid subtle bugs common in languages that silently convert between types. Instead, Rust requires you to explicitly convert values using the as keyword for primitive casts, or the From and Into traits for safer, more expressive conversions between types, including custom ones.
Cricket analogy: Rust won't silently convert a bowler's stats into a batter's stats — you must explicitly re-cast the role with as, or use From/Into like a selector panel formally reclassifying a player from all-rounder to specialist batter.
Syntax
// Using 'as' for primitive casting
let integer = 5;
let float = integer as f64;
let large: i64 = 300;
let small = large as u8; // may truncate
// Using From/Into
let s: String = String::from("hello");
let n: i64 = i64::from(42i32);
let num: i32 = 5;
let num_as_i64: i64 = num.into();Explanation
The as keyword performs an explicit cast between primitive types, such as converting an i32 to an f64, or a larger integer type to a smaller one. Casting between differently sized integer types can truncate data if the target type is too small to hold the value, so as should be used carefully. For safer conversions, especially between custom types or when infallibility is guaranteed, Rust favors the From and Into traits: implementing From<T> for a type automatically gives you the corresponding Into<U> conversion. There is no automatic numeric coercion in Rust; for example, passing an i32 where an f64 is expected will not compile without an explicit conversion.
Cricket analogy: The as keyword is like manually recalculating a batter's strike rate from a T20 innings to fit a Test match context — squeezing a big number like 200 strike rate into a smaller display can truncate meaningful digits, so From/Into is preferred, like an official scorer's verified conversion between formats.
Example
fn main() {
let x: i32 = 5;
let y: f64 = x as f64;
println!("y = {}", y);
let big: i32 = 1000;
let truncated = big as u8; // 1000 % 256 = 232
println!("truncated = {}", truncated);
let celsius: f64 = 100.0;
let fahrenheit = celsius * 9.0 / 5.0 + 32.0;
println!("fahrenheit = {}", fahrenheit);
let n: i64 = i64::from(42i32);
println!("n = {}", n);
}Output
y = 5
truncated = 232
fahrenheit = 212
n = 42Key Takeaways
- Rust never implicitly converts between numeric types; conversion must be explicit.
- The
askeyword performs primitive-to-primitive casts, which can truncate large values. - From and Into traits provide safer, more idiomatic conversions, including for custom types.
- Implementing From<T> automatically provides the reciprocal Into<U> conversion.
- Always be mindful of data loss when casting between integer types of different sizes.
Practice what you learned
1. Does Rust automatically convert an i32 to an f64 when needed?
2. Which keyword is used for primitive type casting in Rust?
3. What can happen when casting a larger integer type to a smaller one with `as`?
4. What is the relationship between the From and Into traits?
5. Which of these correctly converts an i32 value 42 to i64 using From?
Was this page helpful?
You May Also Like
Variables and Data Types in Rust
Learn how Rust variables are immutable by default and explore its scalar and compound data types.
Operators in Rust
Explore Rust's arithmetic, comparison, logical, and bitwise operators with practical examples.
Traits in Rust
Traits define shared behavior that types can implement, similar to interfaces in other languages.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics