Home
Search
Rust usize (Cannot be indexed Error)Access a slice element with an i32 value by casting it to a usize with the as keyword.
Usize, indexes. 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.
String Array
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.
Error example. 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.
Tip The variable "i" is a i32 integer, not a usize, because it is the same type as the fields on the Test struct.
for
Rust program that reveals usize index error
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"); }
DONE
error[E0277]: the type [{integer}] cannot be indexed by i32 ... slice indices are of type usize or ranges of usize
Usize example. 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.
Warning This can cause a slight performance decrease, or even lead to incorrect results if the cast is not successful.
Rust program that shows correct vector indexing
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
Optimized code. Removing excess work from a loop body can often improve code performance. And performance is one of the key goals of writing Rust.
Here We introduce local variables to hold the loop start and end indexes. We cast them to "usize" outside of the loop.
So In the loop body, the variable "i" is a usize already, so no casting needs to be done. This reduces work.
Rust program that avoids casting in loop body
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
A summary. 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.
Home
© 2007-2022 sam allen.
see site info on the changelog.