首页 文章

打印!宏无序执行[重复]

提问于
浏览
2

这个问题在这里已有答案:

我的部分代码如下所示:

print_usage_instructions();
print!("Command: ");
let stdin = io::stdin();
let mut line = String::new();
stdin.lock().read_line(&mut line).expect("Couldn't process the command.");
println!("{}", line);

我期望的行为是这样的:

Usage instructions and stuff
Command: [my command]
[my command]

但是,会发生什么:

Usage instructions and stuff
[my command]
Command: [my command]

任何想法为什么会发生? AFAIK,编译器没有理由在这里更改执行顺序,这部分代码不是异步也不是多线程 .

1 回答

  • 6

    问题: print!() doesn't flush stdout!

    你问,冲洗是什么意思?打印时,您不希望自己将每个字符发送到stdout:这会产生很多开销(想想:做一个系统调用,终端必须更新它的视图,......) . 因此,不是这样做,而是存在一个缓冲区,其中包含即将打印的内容 . 要实际打印,必须刷新此缓冲区 .

    你几乎没有注意到这一切的原因是,当打印换行符( '\n' )时,stdout总是被刷新 . 因此, println!() 总是冲洗!

    您的用例更令人困惑,因为您正在键入stdin . 它的工作原理大致相同:当你输入时,字符还没有发送到任何地方!只有终端/ shell存储您输入的内容 . 但是一旦你点击输入(换行符),你的书面文字就会被提交并发送给stdin .

    无论如何,你可以manually flush stdout而不打印换行符:

    use std::io::{self, BufRead, Write};
    
    fn main() {
        println!("Usage instructions and stuff");
    
        print!("Command:");
        io::stdout().flush().expect("Couldn't flush stdout");   // <-- here
    
        let stdin = io::stdin();
        let mut line = String::new();
        stdin.lock().read_line(&mut line).expect("Couldn't process the command.");
        println!("{}", line);
    }
    

    这种行为之前受到批评:"print! should flush stdout" .


    请注意:您的字符串 line 在最后包含换行符 . 您可以使用trim_right()删除它 . 这与你原来的问题无关,但你也可能遇到这个问题;-)

相关问题