Понимание объема и теневых совпадений
Я пытаюсь немного улучшить окончательный пример кода игры. В частности, я планирую вывести "Пожалуйста, введите число!" если пользователь не вводит число, а не "Пожалуйста, введите ваше предположение". снова. Я делаю это с внутренней петлей. Код ниже работает:
let guess: u32;
loop {
let mut guess_str = String::new();
io::stdin().read_line(&mut guess_str)
.ok()
.expect("Failed to read line");
guess = match guess_str.trim().parse() {
Ok(num) => num,
Err(_) => {
println!("Please input a number!");
continue;
}
};
break;
}
Я хотел бы избежать guess_str
если я могу, правильно затеняя спички. Если я изменю guess_str
в guess
Руст жалуется на use of possibly uninitialized variable: `guess`
, Я не уверен, как переменная может быть неинициализирована, если невозможно, чтобы она не была инициализирована с помощью приведенного выше кода. Есть ли способ сделать это только с помощью guess
?
1 ответ
Давайте посмотрим на более простое воспроизведение:
fn make_guess() -> u32 {
let guess;
{
let mut guess;
guess = 1;
}
guess
}
Здесь вы создаете внешнюю переменную guess
а затем затени его внутри блока. Когда вы назначаете значение 1
в guess
вы присваиваете внутренней переменной. Внешняя переменная никогда не устанавливается на что-либо, поэтому вы получаете ошибку "использование возможно неинициализированной переменной".
Есть ли способ использовать только одну переменную
Косвенно да. Я бы извлек код в функцию. Когда у вас есть удачное предположение, вы можете просто return
, В противном случае вы позволите циклу произойти:
fn make_guess() -> u32 {
loop {
let mut guess = String::new();
io::stdin().read_line(&mut guess)
.ok()
.expect("Failed to read line");
match guess.trim().parse() {
Ok(num) => return num,
Err(_) => {
println!("Please input a number!");
}
}
}
}
Это полностью исключает затенение, исключает необходимость использования явного continue
и добавляет небольшое количество абстракции и организации в ваш код.