我正在从书中学习 Rust ,我刚刚完成第一个练习,猜谜游戏。
我用来cargo构建和运行我的小箱子。
$ cargo --version
cargo 1.37.0 (9edd08916 2019-08-02)
$ rustc --version
rustc 1.37.0 (eae3437df 2019-08-13)
Run Code Online (Sandbox Code Playgroud)
一切都运行良好,包括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.
}
Run Code Online (Sandbox Code Playgroud)
注意到这种系统性的重新分配,我将字符串声明移到了循环之外:
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.
}
Run Code Online (Sandbox Code Playgroud)
然而,Rust 并没有意识到这一点:在循环的第二次迭代中,它每次都会出现恐慌。
为什么我不能多次重复使用同一个可变变量?我是不是没明白什么?
编辑:read_line不清除前一个输入的内容,而是附加以下内容。假设玩家1此时进入2,则猜测的最终值为"1\n2\n"。但是,trim()删除字符串开头和结尾的“空白”字符,\n在中间留下一个:parse()恐慌!
您的代码按原样编译并在我的设置上运行良好(与 Rust 版本相同)。恐慌必须发生在代码的注释掉部分。不过,有一些评论:循环中的范围很棘手:guess循环的上半部分是在循环外部声明的字符串,并且是后半部分中解析的整数。
更重要的是,对read_line传递同一字符串的多次调用会附加到该字符串,考虑到您解析字符串的方式,这可能不是您的意图。加入println!你的猜测变量应该很有启发性。guess.clear()如果您在解析数字后在字符串上添加 a ,您的代码可能会被修复,但要做到这一点,您可能需要重命名 u32 guess。
顺便说一句,您可以考虑使用 BufReader 和此处描述的for line in reader.lines())模式。