#[fastout]
Expand description
Enables buffering for stdout.
You cannot create a closure containing print!
or println!
in #[fastout]
function. This
is because the closure cannot implement Send
since StdoutLock
, which is not a Send
, is
internally captured into the closure. This causes a trait bound mismatch when used with
function requiring its argument closure to be a Send
, such as std::thread::spawn()
.
use proconio::fastout;
use std::thread;
#[fastout]
fn main() {
thread::Builder::new()
.stack_size(32 * 1024 * 1024)
.spawn(|| {
println!("Hi!");
})
.unwrap()
.join()
.unwrap();
}
It is too conservative to make all of such closures compilation error because it is actually no
problem to use such a closure only inside a single thread. However, since trait bound check is
done after macro expansions, there is no way to check whther the closure is required to be a
Send
or not. And the compiler error message for actual mismatch of a Send
requirement is
too confusing, pointing out codes you didn’t write (macro-expanded codes) as an error position.
In conclusion, for user-friendliness, all of them are prohibited for now.
Internally this is the same with
let __proconio_stdout = ::std::io::stdout();
let mut __proconio_stdout = ::std::io::BufWriter::new(__proconio_stdout.lock());
#[allow(unused_macros)]
macro_rules! print {
($($tt:tt)*) => {{
use std::io::Write as _;
::std::write!(__proconio_stdout, $($tt)*).unwrap();
}};
}
#[allow(unused_macros)]
macro_rules! println {
($($tt:tt)*) => {{
use std::io::Write as _;
::std::writeln!(__proconio_stdout, $($tt)*).unwrap();
}};
}
let __proconio_res = {
// Your code goes here
};
<::std::io::BufWriter<::std::io::StdoutLock> as ::std::io::Write>::flush(
&mut __proconio_stdout
).unwrap();
return __proconio_res;