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 = T
and thenU = *T
, ...)
- if there's a method
bar
where the receiver type (the type ofself
in the method) matchesU
exactly , use it (a "by value method")- otherwise, add one auto-ref (take
&
or&mut
of 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