Hi, I'm confused about the following code. If I change &a[..] to a, rustc would complain cannot borrow a as mutable, as it is not declared as mutable.
In my mind, both &a[..] and a are of type &[u8].
BTW, any fast tool to check type of an expression rather than running rustc? I think that'll be suitable for studying rust's strong-n-complicated type system.
use std::io::BufRead;
fn main() {
let aa = String::from("hello\nworld");
let a = aa.as_bytes();
let mut buf = String::new();
assert!(match (&a[..]).read_line(&mut buf) {
Ok(6) => true,
Ok(e) => {
println!("got OK({})", e);
false
}
Err(e) => {
println!("got Err({})", e);
false
}
});
}
They are the same type, &[u8], but &a[..] is a temporary in the expression which can implicitly be mutated. BufRead needs &mut self, which in this case works out to &mut &[u8]. The actual data is still immutable, but when you read a slice, it will be reduced to a slice of the remainder.
It should work with a alone if you declare it let mut a = ..., or you can also force it into a temporary with a block expression, {a}.read_line(&mut buf).
Thank you for the clarification. So it's actually the pointer moving forward as I read.
And a in let mut a= is actually a mut & rather than &mut, which I just confused up.
In Rust references are type just like any other types. The type &'a [u8] implements trait BufRead and since the BufRead::read_line() takes &mut Self, you need to pass &mut &[u8] to this method.