Rust - Type Casting
In Rust, type casting refers to converting a value from one type to another. Rust enforces strict type safety, so you often need to cast explicitly between types, especially when dealing with numeric types. Here’s an overview of type casting in Rust:
1. Numeric Type Casting
Rust provides a way to cast between different numeric types using the as
keyword. However, you must
be careful with potential data loss when casting from a larger type to a smaller one (e.g., i64
to
i32
).
Examples:
rustfn main() {
// Casting an integer to a different size
let x: i32 = 5;
let y: i64 = x as i64;
println!("x: {}, y: {}", x, y);
// Casting a floating-point number to an integer
let a: f32 = 3.9;
let b: i32 = a as i32; // Truncates the decimal part
println!("a: {}, b: {}", a, b);
// Casting a larger integer to a smaller one
let c: u64 = 1000;
let d: u8 = c as u8; // Data loss may occur if c > 255
println!("c: {}, d: {}", c, d);
}
2. Casting Between Primitive Types
You can also cast between primitive types like integers and characters.
Examples:
rustfn main() {
let num: u8 = 97;
let character: char = num as char; // 97 is 'a' in ASCII
println!("num: {}, character: {}", num, character);
let character: char = 'A';
let ascii_value: u8 = character as u8;
println!("character: {}, ascii_value: {}", character, ascii_value);
}
3. Casts That May Fail: Using TryFrom
and TryInto
Some casts may fail or require more careful handling, such as casting between numeric types where the target type
might not be able to hold the value. In these cases, you can use TryFrom
and TryInto
,
which provide safer casting with error handling.
Examples:
rustuse std::convert::TryFrom;
fn main() {
// Using TryFrom to handle possible failure
let large_number: i64 = 300;
let small_number = u8::try_from(large_number);
match small_number {
Ok(num) => println!("Successfully casted: {}", num),
Err(_) => println!("Failed to cast"),
}
// Using TryInto for a more concise syntax
let result: Result<u8, _> = large_number.try_into();
match result {
Ok(num) => println!("Successfully casted: {}", num),
Err(_) => println!("Failed to cast"),
}
}
4. From and Into Traits
Rust also provides the From
and Into
traits for type conversion. These traits are more
idiomatic and are preferred when you know the conversion is safe and should never fail.
Examples:
rustfn main() {
// Using From trait for safe conversion
let num: i32 = 5;
let num_as_string = String::from(num.to_string());
println!("Number as string: {}", num_as_string);
// Using Into trait for conversion
let num_as_string: String = num.to_string().into();
println!("Number as string: {}", num_as_string);
}
5. Floating-Point to Integer Casting
Casting from a floating-point number to an integer truncates the decimal part, as shown earlier. This behavior is important to note to avoid unexpected results.
Summary
- Numeric Casting: Use the
as
keyword for casting between numeric types. - Primitive Types: Convert between types like integers and characters using
as
. - Error-Prone Casting: Use
TryFrom
andTryInto
for casting that might fail. - Idiomatic Conversions: Use
From
andInto
traits for more idiomatic type conversions.
This should cover the essentials of type casting in Rust!