Why a rust immutable reference can call &mut self methd?
in my code comments:
use std::io::{self, Write};
use std::process::{Command, Stdio};
fn main() -> io::Result<()> {
let child = Command::new("cmd.exe")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()?;
let mut stdin = child.stdin.as_ref().unwrap();
//1. stdin's type is &ChildStdin, why can call a "&mut self" function write_all?
stdin.write_all(b"dir\n")?;
//2. and why as_ref result can call a "&mut self" function write_all?
child.stdin.as_ref().unwrap().write_all(b"dir\n")?;
let output = child.wait_with_output()?;
println!("output = {:?}", output);
Ok(())
}
In the documentation of ChildStdin
, you can find the impl Write for &ChildStdin
. This was added in 1.48 because these writes are supposedly safe to call, according to the original issue:
The implementations of Write which are MT-safe under the covers can implement a trait along the lines of [...] and some already do [...]. However, these appear to be the extent of the current implementations. The following types could also do the same:
- [...]
- ChildStdin – similar to File or *Streams;
and the PR.
Notably, we don't have a &mut ChildStdin
at any point. Instead, you create a mutable reference to the immutable reference, a &mut &ChildStdin
. This mutable reference is then given to the write_all
trait method from the linked Write
implementation for &ChildStdin
.
While there is a impl Write for ChildStdin
too (which would need a &mut ChildStdin
), we don't actually use it here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With