I am a new rustacean.
we have Deref Coercions yet. So when should we add the * notation to the code by ourselves? Just when compiler mentioned?
like this code 1:
fn main() {
let mut v = vec![1, 2, 3];
{
let foobar = &mut v;
foobar[0] = foobar[1] + 1;
}
println!("{}", v[0]);
}
and this code 2:
fn main() {
let mut v = vec![1, 2, 3];
{
let foobar = &mut v;
(*foobar)[0] = (*foobar)[1] + 1;
}
println!("{}", v[0]);
}
These two codes did the same thing and have the same result.
I guess the reason is compiler did the Deref Coercions for code 1. (The real reason is auto-deref)
So, in the real-situations, What kind of the code should we write? code 1 or code 2?
Thank you!
Result:
from our discussion, we think that you should use Deref notation only when required.
First time, you may write the code without them, and add them by compiler's error message. You'd better understand why there should be Deref notation.
To avoid mixing up terms, deref coercion is a different (albeit related) feature; what’s being discussed in this thread is auto-deref (vs explicit deref).
fn takes_str_slice(s: &str) {}
fn main() {
let s = "hello".to_string();
takes_str_slice(&s);
}
Technically, &s forms a &String. However, the compiler will perform a deref coercion to &str there, which is allowed because String: Deref<str>. Similarly, you can coerce a Vec<T> to a &[T]. There are certain contexts, such as method calls, where the compiler will attempt coercion if the immediate type is not valid (like in the above case where &String is an invalid type for the call).
auto deref is basically done by method calls. The dot operator there removes as many layers of reference as necessary to make the call:
// this is a &'static str
let s = "hello”;
// this is &&&...&'static str
let x = &&&&&&&&&&s;
// method call strips off as many layers of refs as needed
let len = x.len();
There’s a related autoref, which automatically borrows a value to make a method call on it:
let mut v = vec![1];
// autoref to get the &mut self for the push() call
v.push(2);
What others have said is a good starting point. In general, use it only when required - compiler will tell you about those cases. And when they happen, try to understand why it’s required there - ask for help/clarification here if needed.