Home
Rust
usize (Cannot be indexed Error)
This page was last reviewed on May 3, 2023.
Dot Net Perls
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.
Cast
AtomicUsize
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
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.
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.
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.
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 3, 2023 (edit link).
Home
Changes
© 2007-2024 Sam Allen.