When developing in Rust, numeric types like i32
cannot be used as indexes to a slice or vector. This causes an error for new Rust developers.
By casting to usize
, we can eliminate the "cannot be indexed" error. This may cause a slight performance cost, so it is best avoided with code changes.
To begin, we see the code that will cause the "cannot be indexed" error. If we try to run the code that was commented out, the program will not compile.
i32
integer, not a usize
, because it is the same type as the fields on the Test struct
.struct Test { start: i32, end: i32 } fn main() { let value = vec![10, 20, 30]; // Create struct with 2 i32 fields. let test = Test{start: 1, end: 2}; // This won't compile because "i" is not a usize. for i in test.start..=test.end { // let element = value[i]; // println!("ELEMENT: {}", element) } println!("DONE"); }DONEerror[E0277]: the type [{integer}] cannot be indexed by i32 ... slice indices are of type usize or ranges of usize
Here we see the Rust code that has been corrected to compile and run. We must cast the variable "i" to a usize
with the "as" keyword.
struct Test { start: i32, end: i32 } fn main() { let value = vec![10, 20, 30]; let test = Test{start: 1, end: 2}; for i in test.start..=test.end { // Change the "i" to a usize to access a vec element. let element = value[i as usize]; println!("ELEMENT: {}", element) } println!("DONE"); }ELEMENT: 20 ELEMENT: 30 DONE
Removing excess work from a loop body can often improve code performance. And performance is one of the key goals of writing Rust.
usize
" outside of the loop.usize
already, so no casting needs to be done. This reduces work.struct Test { start: i32, end: i32 } fn main() { let value = vec![10, 20, 30]; let test = Test{start: 1, end: 2}; // Cast once, to avoid casting in the loop body. let start = test.start as usize; let end = test.end as usize; // Loop. for i in start..=end { let element = value[i]; println!("ELEMENT: {}", element) } println!("DONE"); }ELEMENT: 20 ELEMENT: 30 DONE
Some parts of Rust are confusing and annoying at first. But with some understanding, the "cannot be indexed" issue with usize
can be avoided. This can even lead to better code.