我的部分代码如下所示:
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,编译器没有理由在这里更改执行顺序,这部分代码不是异步也不是多线程。
答案 0 :(得分:6)
问题: print!()
没有刷新标准输出!
刷新是什么意思,你问?打印时,你不想自己将每个字符发送到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()
将其删除。这与你原来的问题无关,但你也可能遇到这个问题;-)