mut 字符串在循环内重新声明

mut String redeclaration inside loop

我正在阅读 Rust 书,猜谜游戏教程有以下代码:

use rand::Rng;
use std::cmp::Ordering;
use std::io;
use std::io::Write;

fn main() {
    let secret_number = rand::thread_rng().gen_range(1, 101);
    let mut input = String::new();

    loop {
        print!("Guess the number I'm thinking of: ");
        io::stdout().flush().unwrap();
        io::stdin().read_line(&mut input).expect("Failed to read line");

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

        println!("\nYou guessed: {}", guess);

        match guess.cmp(&secret_number) {
            Ordering::Less => println!("Too small!"),
            Ordering::Greater => println!("Too big!"),
            Ordering::Equal => {
                println!("You win!");
                break;
            }
        }
    }
}

此代码在第一次用户输入后失败。如果我在循环内移动 let mut input = String::new(); 声明,那么一切正常......但我想知道为什么我必须这样做,因为 input 的地址被传递到 read_line()?

还有一件事,为什么我必须使用 std::io::Write 才能使用 io::stdout().flush().unwrap();,因为我已经在使用 use std::io;

io::stdin().read_line(&mut input);

此方法不会覆盖 String but it appends to the String. This is why only the first iteration of the loop works but it immediately breaks on the second iteration. If you want to re-use the String buffer between iterations you need to truncate it before passing it back into read_line。固定工作示例:

use rand::Rng;
use std::cmp::Ordering;
use std::io;
use std::io::Write;

fn main() {
    let secret_number = rand::thread_rng().gen_range(1, 101);
    let mut input = String::new();

    loop {
        print!("Guess the number I'm thinking of:");
        io::stdout().flush().unwrap();
        
        input.clear(); // truncate String buffer here!

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

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

        println!("\nYou guessed: {}", guess);

        match guess.cmp(&secret_number) {
            Ordering::Less => println!("Too small!"),
            Ordering::Greater => println!("Too big!"),
            Ordering::Equal => {
                println!("You win!");
                break;
            }
        }
    }
}

And one more thing why do I have to use std::io::Write in order to use io::stdout().flush().unwrap(); since I'm already using use std::io;?

为了调用特征方法,您需要将特征纳入范围。 flush is defined by the Write 特质。