rust - 为什么需要在循环的每次迭代中声明一个变量才能使用它?

标签 rust

我正在从 The Book 学习 Rust我刚刚完成第一个练习,guessing game .

我使用 cargo 来构建和运行我的小箱子。

$ cargo --version
cargo 1.37.0 (9edd08916 2019-08-02)
$ rustc --version
rustc 1.37.0 (eae3437df 2019-08-13)

一切都运行良好,包括release模式。尽管如此,我不理解 Rust 的以下行为:我必须在循环的每次迭代中重新声明包含用户输入的变量。

由于练习是逐步指导的,因此我的代码与书中的代码相同。尽管如此,书中的代码如下:

loop {
    // Some code to display instructions.

    // Reallocate a new string at each iteration!
    let mut guess = String::new();

    io::stdin().read_line(&mut guess)
        .expect("Failed to read line");

    let guess: u32 = match guess.trim().parse() {
        Ok(num) => num,
        Err(_) => continue,
    };

    // Some code to check if the player found the secret number.
}

注意到这种系统性的重新分配,我将字符串声明移到循环之外:

// Allocate the string once.
let mut guess = String::new();

loop {
    // Some code to display instructions.

    io::stdin().read_line(&mut guess)
        .expect("Failed to read line");

    let guess: u32 = match guess.trim().parse() {
        Ok(num) => num,
        Err(_) => continue,
    };

    // Some code to check if the player found the secret number.
}

然而,Rust 并没有意识到这一点:在循环的第二次迭代中,它每次都会出现 panic 。

为什么我不能多次重复使用同一个可变变量?我是不是没明白什么?

编辑:read_line清除前一个输入的内容,但会附加以下内容。 假设玩家输入1,然后输入2,则最终猜测值将是“1\n2\n”。 但是,trim() 会删除字符串开头和结尾的“空白”字符,在中间留下 \n:parse() panic !

最佳答案

您的代码按原样编译并在我的设置上运行良好(与 Rust 版本相同)。 panic 必须发生在代码的注释掉部分。不过,有一些评论:循环中的范围很棘手:循环上半部分的 guess 是在循环外部声明的字符串,并且是后半部分中解析的整数。

更重要的是,多次调用 read_line 传递的同一字符串会附加到该字符串,考虑到您解析字符串的方式,这可能不是您的意图。加入 println! 的猜测变量应该很有启发性。如果您在解析数字后在字符串上添加 guess.clear() ,您的代码可能会被修复,但要做到这一点,您可能需要重命名 u32 猜猜

顺便说一句,您可以考虑使用 BufReader 和 for line in reader.lines()) 模式 described here.

关于rust - 为什么需要在循环的每次迭代中声明一个变量才能使用它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57897931/

相关文章:

rust - 如何从主泛型推论出子泛型?

rust - 使用 Cargo 为使用相同源目录的多个平台构建的最佳方式是什么?

macros - 如何有条件地更改 Rust 宏的一小部分?

visual-studio-code - 如何获取要显示的类型提示?

rust - 返回本地String作为切片(&str)

serialization - 如何在不包含枚举变体名称的情况下序列化枚举?

rust - 如何指定特征迭代器?

windows - 无法从 WinApi crate 调用 CryptDecrypt,因为它找不到模块

rust - 为什么在 Rust 中使用不可变的 Vector 或 String

unit-testing - 如何为需要引用“静态生命周期并实现同步”的函数提供模拟值?