Rust中say函数调用在前却输出在后的原因咨询
问题
作为Rust新手,运行以下代码时发现,先调用的say函数输出反而出现在目录遍历结果之后,想确认是否和unwrap方法有关。
运行代码
#![allow(unused)] // For beginning only. use std::fs::read_dir; use std::io::{BufWriter, stdout}; use ferris_says::say; use crate::prolog::*; mod error; mod prolog; mod utils; fn main() -> Result<()> { let stdout = stdout(); let message = String::from("Hello fellow Rustaceans!"); let width = message.chars().count(); let mut writer = BufWriter::new(stdout.lock()); say(&message, width, &mut writer).unwrap(); for entry in read_dir("./")?.filter_map(|e| e.ok()) { let entry: String = W(&entry).try_into()?; println!("{entry}"); } Ok(()) }
运行输出
/Users/eric.kolotyluk/.cargo/bin/cargo run --color=always --package hello-rust --bin hello-rust Finished dev [unoptimized + debuginfo] target(s) in 0.00s Running `target/debug/hello-rust` ./Cargo.toml ./target ./Cargo.lock ./.gitignore ./hello-rust.iml ./.git ./.idea ./src __________________________ < Hello fellow Rustaceans! > -------------------------- \ \ _~^~^~_ \) / o o \ (/ '_ - _' / '-----' \ Process finished with exit code 0
原因与解决办法
这个现象和unwrap无关,问题出在**BufWriter的延迟写入特性**:
BufWriter是带缓冲的写入器,它会先把数据暂存在内存缓冲区中,不会立刻输出到控制台。只有当缓冲区被填满、手动触发刷新,或者BufWriter被销毁时,才会把缓冲区内容一次性输出。println!函数内部会自动刷新标准输出的缓冲区,所以目录遍历的内容会直接打印出来。- 程序运行到末尾时,
writer变量被销毁,BufWriter的析构函数才会执行刷新操作,把say函数写入的内容输出,因此它的结果出现在最后。
解决方法
在调用say之后,手动调用flush方法强制刷新缓冲区,就能让say的内容立刻输出:
let mut writer = BufWriter::new(stdout.lock()); say(&message, width, &mut writer).unwrap(); writer.flush().unwrap(); // 手动刷新缓冲区
内容的提问来源于stack exchange,提问作者Eric Kolotyluk
相关产品推荐
相关产品推荐

