Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does String implicitly convert to &str in Rust?

Tags:

string

rust

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.

like image 550
chenzhongpu Avatar asked Sep 16 '25 11:09

chenzhongpu


1 Answers

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, set U = T and then U = *T, ...)
    1. if there's a method bar where the receiver type (the type of self in the method) matches U exactly , use it (a "by value method")
    2. 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:

  1. First dereference step (no deref):
    1. Can you call String::chars(s)? No.
    2. What about &String or &mut String? No.
  2. Second dereference step: <String as Deref>::Target = str, so we are looking for methods of str. let c: str = *s (assuming this DST type was allowed);
    1. Can you call str::chars(c)? No.
    2. Can you call str::chars(&c)? Yes!
like image 128
Peter Hall Avatar answered Sep 18 '25 08:09

Peter Hall