techmore.in

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:

rust
fn 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:

rust
fn 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:

rust
use 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:

rust
fn 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 and TryInto for casting that might fail.
  • Idiomatic Conversions: Use From and Into traits for more idiomatic type conversions.

This should cover the essentials of type casting in Rust!