Reputation: 4454
I am referring to the type of the guess
variable. It seems that the type changes from a String
then to an i32
and then back to a String
.
use std::{any::Any, io};
fn print_type_of<T>(_: &T) {
println!("{}", std::any::type_name::<T>())
}
fn main() {
let mut guess = String::new();
loop {
print_type_of(&guess);
guess.clear();
io::stdin()
.read_line(&mut guess)
.expect("Failed to read line");
let guess: i32 = match guess.trim().parse() {
Ok(x) => x,
Err(_) => continue,
};
print_type_of(&guess);
if guess == 69 {
break;
}
}
println!("{}", guess);
}
I can understand the concept of shadowing in a linear and scoped context. But after the guess
has been shadowed and becomes an i32
, I am surprised to find that when going back at the top of the loop, it suddenly changes back to a String
type!?!?
Upvotes: 0
Views: 121
Reputation: 70950
Shadowing does not follow control flow, it is linear with the source code. At the loop entry, you have one guess
with type String
. When you declare let guess: i32
, you introduce a new variable named guess
with the type i32
. You cannot access the original guess
because it is shadowed, but it's still there. We don't "loop again": we just inspect all guess
variables in the current scope, and the one you're referring to is the closest one. When you are after the second guess
declaration it's it; when you're before it's the first guess
. You may find it more natural if you'll think of each variable as having a number attached:
fn main() {
let mut guess_1 = String::new();
loop {
print_type_of(&guess_1);
guess_1.clear();
io::stdin()
.read_line(&mut guess_1)
.expect("Failed to read line");
let guess_2: i32 = match guess_1.trim().parse() {
Ok(x) => x,
Err(_) => continue,
};
print_type_of(&guess_2);
if guess_2 == 69 {
break;
}
}
println!("{}", guess_1);
}
Upvotes: 1