理解作用域和隐藏匹配

3
我正在尝试改进最终的猜数字示例代码。特别是,如果用户没有输入数字,我计划输出“请输入数字!”而不是再次输出“请输入你的猜测。” 我用内部循环来实现这个功能。下面的代码可以工作:
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,Rust会抱怨use of possibly uninitialized variable: `guess`。如果按照上面的代码,变量不可能未初始化,那么它怎么可能未初始化呢?有没有什么方法只使用guess来实现这一点?
1个回答

4
让我们来看一个更简单的复制:
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语句,并且为您的代码添加了一些抽象和组织。

好的,这很有道理。不确定为什么我之前没有看到。在我的例子中有没有只使用一个变量的方法? - Explosion Pills

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接