Topic Overview

Greetings, budding Rustaceans! Are you ready to delve into some fundamental knowledge about Rust? Today's journey will take us into the heart of the Rust language: Data Type Conversion. Often, we need to convert one data type to another for a different representation in our programs, much like translating alien languages in a Sci-Fi adventure. We'll focus on both automatic and explicit conversions, as well as potential pitfalls. So, fasten your seatbelts, and let's dive in!

Automatic (Implicit) Conversions

In Rust, unlike some other languages, automatic conversion of types isn't allowed. This restriction stems from Rust's focus on type safety, put in place to avoid unintended consequences of type conversion that may lead to bugs in the software.

Rust doesn't automatically treat an i32 (integer) as an f64 (floating point), or vice versa. Here's what happens when you attempt to do so:

let i: i32 = 10;  // an integer 
let d: f64 = i;  // error: expected `f64`, found `i32` 

Rust will throw a compile-time error stating it expected a f64 but found an i32 instead.

Manual (Explicit) Conversions

To convert between types in Rust, we must manually specify the conversion. This requirement is akin to a human (symbolizing f64) trying to fit into space suit designed for space dog (i32). We must explicitly modify the space dog suit to be human sized.

Here's how to convert an i32 to a f64:

let i: i32 = 10;  // an integer 
let d: f64 = i as f64;  // explicit conversion to f64

println!("The value of d: {}", d);   // Output: The value of d: 10

And here's how to convert from a f64 to an i32:

let d: f64 = 10.75; // a f64 number
let i: i32 = d as i32;  // casting the double to int

println!("The value of i: {}", i);  // Output: The value of i: 10

Notice that the decimal part of 10.75 gets truncated during the conversion process, leaving only 10.

Type Safety in Arithmetic Operations

In Rust, strict type safety rules extend to arithmetic operations as well. This means that Rust doesn't implicitly convert types for addition or other arithmetic operations.

For example, it's invalid to add an i32 value to an f32 value. You might expect this to work because it seems reasonable to add integers and floating-point numbers. However, for the purpose of safeguarding type safety, Rust disallows this operation. Here's what happens when you try to add variables of types i32 and f32:

let a: i32 = 10;    // an integer
let b: f32 = 10.5;  // a floating point number

let c = a + b;     // error: expected `f32`, found `i32`

Rust will throw a compile-time error, stating that it expected an f32 but found an i32 instead. This is because Rust can't automatically convert a from i32 to f32 to make the addition possible.

If you intend to perform this operation, you must explicitly convert the i32 value to an f32 value like so:

let a: i32 = 10;     // an integer
let b: f32 = 10.5;  // a floating point number

let c = a as f32 + b;     // explicit conversion of `a` to `f32`
println!("The value of c: {}", c); // prints "The value of c: 20.5"

Now, c will hold the value 20.5, as expected. This explicitness of conversions is a part of Rust's dedication to preventing bugs and easing debugging, even though it may require a bit more code.

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal