Type Conversion
Prerequisites: Scalar data types
Rust never converts between number types automatically — not even
from i32 to i64. You always convert explicitly.
Syntax
let n = 3.99_f64 as i32; // cast with `as`
let wide = i64::from(42_i32); // lossless conversion with `from`
let parsed: i32 = "42".parse().expect("not a number");
as casts convert between number types, and between numbers and
characters:
- Float to integer truncates toward zero:
3.99 as i32is3. - Casting to a smaller integer type keeps only the low bits, which can
change the value:
300 as u8is44. Be careful with this. 'A' as u32is65, and97_u8 as charis'a'.
T::from(value) only exists for conversions that can never lose
information (like i32 to i64), so it's the safer choice when
available.
Parsing text uses .parse(). Parsing can fail — "abc" isn't a
number — so parse returns a Result: either Ok(value) or
Err(error). Rust needs to know what type you want, so give the
variable a type (let n: i32 = ...) or use the "turbofish" syntax
"42".parse::<i32>().
At this stage, there are two simple ways to handle the Result:
.expect("message")— gives you the value, or stops the program with your message if parsing failed.match— runs different code forOkandErr. (The Enums & match lesson explainsmatchfully.)
Example
fn main() {
let price = 19.99_f64;
let whole = price as i32;
println!("{price} as i32 = {whole}");
let big = 300_i32;
println!("{big} as u8 = {}", big as u8);
println!("'A' as u32 = {}", 'A' as u32);
println!("97 as char = {}", 97_u8 as char);
let small: i32 = 42;
let wide = i64::from(small);
println!("i64::from = {wide}");
let count: i32 = "42".parse().expect("not a number");
println!("parsed + 1 = {}", count + 1);
let result = "abc".parse::<i32>();
match result {
Ok(n) => println!("Parsed {n}"),
Err(e) => println!("Could not parse: {e}"),
}
}
Expected output
19.99 as i32 = 19
300 as u8 = 44
'A' as u32 = 65
97 as char = a
i64::from = 42
parsed + 1 = 43
Could not parse: invalid digit found in string
Common mistakes
- Mixing number types in arithmetic.
let count: i32 = 3;
let price: f64 = 2.5;
let total = count * price;
error[E0277]: cannot multiply `i32` by `f64`
Convert one side first: count as f64 * price.
- Not saying which type to parse into.
let n = "5".parse().unwrap();fails with:
error[E0284]: type annotations needed
- Parsing text that has spaces or a newline around it.
" 42".parse::<i32>()is an error — call.trim()first (you'll need this when reading user input). - Assuming
asrounds. It truncates; useprice.round() as i32to round to the nearest whole number.
Practice
Parse the text "19" into an i32 and "3.5" into an f64, multiply
them (converting the i32 first), and print Total: 66.5.
Show solution
fn main() {
let quantity: i32 = "19".parse().expect("not an integer");
let price: f64 = "3.5".parse().expect("not a number");
let total = quantity as f64 * price;
println!("Total: {total}");
}