Considering the following code:
let s = String::from("hello");
let mut r = String::new();
for c in s.chars() {
r.push(c);
}
As chars is the method of &str, why can String call it? I suppose it has something to do with the coercion, but I don't fully understand this implicit conversion.
This is actually covered in this question: What are Rust's exact auto-dereferencing rules?. There is a lot going on in that answer, so I will try to apply it to your question.
To quote huon's answer:
The core of the algorithm is:
- For each "dereference step"
U(that is, setU = Tand thenU = *T, ...)
- if there's a method
barwhere the receiver type (the type ofselfin the method) matchesUexactly , use it (a "by value method")- otherwise, add one auto-ref (take
&or&mutof the receiver), and, if some method's receiver matches&U, use it (an "autorefd method")
The key is in the "dereference steps": U = *T means let u = Deref::deref(t);, where u: U, t: T. We keep doing that until something can't be dereferenced any more.
Following that algorithm for the call to s.chars() from your code:
String::chars(s)? No.&String or &mut String? No.<String as Deref>::Target = str, so we are looking for methods of str. let c: str = *s (assuming this DST type was allowed);
str::chars(c)? No.str::chars(&c)? Yes!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