Cast Examples
This page was last reviewed on May 22, 2023.
Dot Net Perls
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.
Important 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.
Dot Net Perls is a collection of tested code examples. Pages are continually updated to stay current, with code correctness a top priority.
Sam Allen is passionate about computer languages. In the past, his work has been recommended by Apple and Microsoft and he has studied computers at a selective university in the United States.
This page was last updated on May 22, 2023 (edit).
© 2007-2024 Sam Allen.