Hello,
I've been wondering why Box
implements so many traits. (I'm not the only one.)
For example it implements BufRead
if the target type does so as well. Let's consider the following program:
use std::io;
use std::io::prelude::*;
trait Greet {
fn greet(&self) { println!("Hello"); }
}
impl<'a> Greet for io::StdinLock<'a> {}
fn main() -> Result<(), io::Error> {
// Type io::StdinLock implements BufRead.
let mut lstdin: Box<io::StdinLock> = io::stdin().lock().into();
let mut line = String::default();
// The following works because Box implements BufRead:
lstdin.read_line(&mut line)?;
// The following also works for the same reason:
Box::read_line(&mut lstdin, &mut line)?;
println!("{}", line);
// The following works because of Box' Deref impl:
lstdin.greet();
// The following doesn't work because Box does not implement Greet directly:
// Box::greet(&lstdin);
Ok(())
}
So OK, it seems that if Box
didn't implement BufRead
, the program would still work, only that we would have to call read_line
as a method and couldn't call Box::read_line
instead. But that's probably OK. After all, other std smart pointers do not implement BufRead
. (But they do implement other traits if their target does.)
Are there guidelines on which traits smart pointers should "forward" and which not? Or is this forwarding perhaps a leftover from before Deref
existed?