Распечатать! макрос выполняется не в порядке
Часть моего кода выглядит так:
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 ответ
Эта проблема: print!()
не сбрасывает стандартный вывод!
Вы спрашиваете, что означает промывка? При печати вы не хотите отправлять каждый символ в stdout самостоятельно: это может привести к большим накладным расходам (подумайте: при выполнении системного вызова терминал должен будет обновить свое представление, ...). Таким образом, вместо того, чтобы сделать это, существует где-то буфер, который содержит содержимое, которое должно быть напечатано. Чтобы на самом деле печатать, этот буфер должен быть очищен.
Причина, по которой вы едва замечаете все это, в том, что stdout всегда сбрасывается при переводе строки ('\n'
) печатается. Таким образом, println!()
всегда вспыхивает!
Ваш вариант использования еще более запутанный, потому что вы вводите в stdin. Здесь все работает примерно так же: когда вы печатаете, символы еще никуда не отправляются! Только терминал / оболочка хранит то, что вы набрали. Но как только вы нажмете клавишу ввода (перевод строки), ваш письменный текст будет отправлен и отправлен на стандартный ввод.
В любом случае, вы можете вручную сбросить стандартный вывод без печати новой строки:
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!
должен смывать стандартный вывод ".
И, пожалуйста, обратите внимание: ваша строка line
содержит символ новой строки в самом конце. Вы можете удалить это с trim_right()
, Это не имеет ничего общего с вашим первоначальным вопросом, но вы, скорее всего, столкнетесь и с этой проблемой;-)