【问题标题】:print! macro gets executed out of order [duplicate]打印!宏被乱序执行[重复]
【发布时间】:2018-09-11 10:15:03
【问题描述】:

我的部分代码如下所示:

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,编译器没有理由在这里更改执行顺序,这部分代码既不是异步也不是多线程。

【问题讨论】:

    标签: rust rust-macros


    【解决方案1】:

    问题:print!() 没有刷新标准输出!

    flushing 是什么意思,你问?打印时,您不想将每个字符都单独发送到标准输出:这会产生很多开销(想想:进行系统调用,终端必须更新其视图,...)。因此,不是这样做,而是在某处存在一个缓冲区,该缓冲区保存即将打印的内容。要实际打印,必须刷新此缓冲区

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

    您的用例更加令人困惑,因为您正在输入标准输入。在这里它的工作方式几乎相同:当您键入时,字符还没有发送到任何地方!只有终端/shell 存储您输入的内容。但是一旦你按下回车(换行符),你的书面文本就会被提交并发送到标准输入。

    无论如何,您可以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() 将其删除。这与您最初的问题无关,但您也可能会遇到这个问题;-)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-15
      • 2015-04-08
      • 2018-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多