Andrew
Andrew

Reputation: 8673

Using loop variable from ".." loop causes type conversion?

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

Answers (1)

DK.
DK.

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

Related Questions