【问题标题】:Why do I need to declare a variable at each iteration of a loop to use it?为什么我需要在循环的每次迭代中声明一个变量才能使用它?
【发布时间】:2019-09-11 23:25:44
【问题描述】:

我正在从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 不明白这一点:在循环的第二次迭代中,它每次都会恐慌。

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

编辑:read_line 确实清除前一个输入的内容,而是将下一个输入附加到它上面。 假设玩家输入1,然后输入2,猜测的最终值将是"1\n2\n"。 但是,trim() 删除了字符串开头和结尾的“空白”字符,在中间留下了 \nparse() 恐慌!

【问题讨论】:

    标签: rust


    【解决方案1】:

    您的代码按原样编译并在我的设置上运行良好(相同版本的 rust)。恐慌必须发生在代码的注释掉部分。但是,有些 cmets:循环中的范围很棘手:循环上半部分的 guess 是在循环外声明的字符串,是下半部分的解析整数。

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

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

    【讨论】:

    • 你是绝对正确的,read_line 将输入附加到前一个字符串;调试器向我展示了在第二轮 - 假设 1 然后 2 - guess 包含 "1\n2\n"guess.clear()就在输入解决问题之前!谢谢!
    • 我编辑了我的答案以包含修复:在每个 read_line 之前调用guess.clear()。
    猜你喜欢
    • 2014-12-01
    • 1970-01-01
    • 2019-12-19
    • 2016-07-04
    • 1970-01-01
    • 2011-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多