Rust Cast ExamplesUse casts to change the types of values. Apply the as keyword, and the from and into functions.
Casts. In Rust we have several syntaxes for casting values—we can use the "as" keyword, or use the from and into functions. Usually these compile to the same thing.
With no casts, less code is generated, so programs will be faster—it is worth trying to avoid casting. But this is not always possible.
First example. This program shows 2 example methods, add1 and add2. These both receive two byte values (u8) and then return an unsigned 32-bit integer.
Tip When inspecting the output of this program when optimized by LLVM, the methods have the same instructions.
And The compiler can merge the two functions and just treat them as a single function.
fn add1(a: u8, b: u8) -> u32 { // Cast both arguments to u32, then add them and return a u32. (a as u32) + (b as u32) } fn add2(a: u8, b: u8) -> u32 { // Same as first version. (u32::from(a) + u32::from(b)).into() } fn main() { println!("{}", add1(1, 2)); println!("{}", add2(1, 2)); }
3 3
Into, String. With into() we have access to some more powerful conversion routines. For example, we can use into to get a Vector of bytes from a String.
fn print_bytes(values: Vec<u8>) { for v in values { println!("{v}"); } } fn main() { let initial = "abc".to_string(); // String implements From::string into Vec of u8. print_bytes(initial.into()); }
97 98 99
Compile-time error. If we try to use into() to convert a type in a way that is not supported, we will get a trait bound error. This means our code needs to be changed.
fn test(values: Vec<char>) { // Does not work. } fn main() { let initial = "abc".to_string(); // String does not implement From::string into Vec of char. test(initial.into()); }
error[E0277]: the trait bound Vec<char>: From<String> is not satisfied
Cast slice, array. It is possible to use try_into() to cast a slice to an array of the same number of elements. The counts of elements must match or an error will be encountered.
Here We have a 4-element array, and then take a slice of 2 elements at its start. Then we use try_into to cast to a 2-element array.
Unwrap After calling try_into() we must call unwrap() to get the inner value of the result.
fn print_array(values: [u8; 2]) { println!("{:?}", values); } fn main() { let data = [10, 20, 30, 40]; // Get slice from the array, and then convert to an array of the specified length. print_array(data[..2].try_into().unwrap()); }
[10, 20]
Performance notes. In the compiler, casts seem to cause the "movzw" instruction to be generated in assembly. If the casts are removed (due to a refactoring) these instructions are not needed.
So If we can refactor a method to not need any casting, it will have fewer instructions and may execute faster.
Tip Try changing the types of data structures to match those used in functions—avoiding casting in functions can speed them up.
Summary. Casting and conversions in Rust can be done with several syntaxes. These casts are not free in terms of performance, and avoiding them can speed up important functions.
© 2007-2022 sam allen.
see site info on the changelog.