Reputation: 8673
I have a really simple timing loop that users ..
up to a maximum. However, when I use the loop variable inside the block (here as an index) it appears to cause the variable type to change. If I do not touch the loop variable then the stopwatch has no issue.
let sw = Stopwatch::start_new();
let all_data = vec!["a", "b", "c", "d", "e"];
let iters = 2;
for x in 0..iters {
println!("Message: {:?}", all_data[x]);
}
println!("Thing took {}ms per", sw.elapsed_ms() / iters);
This give me a type error when printing out the elapsed time. It appears to have changed to a usize
?
I can fix this by using all_data[x as usize]
though. Is Rust actually changing the actual variable somehow, or is the type inference just taking the very last usage and assuming that type?
src/main.rs:95:55: 95:58 error: mismatched types [E0308]
src/main.rs:95 println!("Thing took {}ms per", sw.elapsed_ms() / iters);
^~~
<std macros>:2:27: 2:58 note: in this expansion of format_args!
<std macros>:3:1: 3:54 note: in this expansion of print! (defined in <std macros>)
src/main.rs:95:5: 95:60 note: in this expansion of println! (defined in <std macros>)
src/main.rs:95:55: 95:58 help: run `rustc --explain E0308` to see a detailed explanation
src/main.rs:95:55: 95:58 note: expected type `i64`
src/main.rs:95:55: 95:58 note: found type `usize`
src/main.rs:95:37: 95:58 error: the trait bound `i64: std::ops::Div<usize>` is not satisfied [E0277]
src/main.rs:95 println!("Thing took {}ms per", sw.elapsed_ms() / iters);
Upvotes: 0
Views: 3016
Reputation: 59095
What type is x
?
let iters = 2;
Well, the let
doesn't specify a type, and a bare 2
could be any kind of integer, so... I dunno.
0..iters
Well, a bare 0
could be any kind of integer, so... I dunno.
all_data[x]
A-ha! There's only one implementation of Index
usable on a Vec
, and it's Index<usize>
, which means x
must be a usize
, which means 0..iters
must be a Range<usize>
, which means iters
must be a usize
!
(But if you don't use it...)
Well, I never got any indication as to what the type of x
was, and it must have a type, so... i32
? *shrug*
Integer types default to i32
in the absence of more conclusive inference information. By using it to index a Vec
, you told Rust that it's supposed to be a usize
.
Upvotes: 12