Понимание объема и теневых совпадений

Я пытаюсь немного улучшить окончательный пример кода игры. В частности, я планирую вывести "Пожалуйста, введите число!" если пользователь не вводит число, а не "Пожалуйста, введите ваше предположение". снова. Я делаю это с внутренней петлей. Код ниже работает:

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и добавляет небольшое количество абстракции и организации в ваш код.

Другие вопросы по тегам