Почему String неявно преобразуется в & str в Rust? - PullRequest
2 голосов
/ 20 сентября 2019

Учитывая следующий код:

let s = String::from("hello");
let mut r = String::new();

for c in s.chars() {
    r.push(c);
}

Поскольку chars является методом &str, почему String может вызывать его?Я предполагаю, что это как-то связано с coercion, но я не совсем понимаю это неявное преобразование.

1 Ответ

1 голос
/ 20 сентября 2019

Это на самом деле рассматривается в этом вопросе: Каковы точные правила автоматической разыменования в Rust? .В этом ответе много чего происходит, поэтому я постараюсь применить его к вашему вопросу.

Процитирую ответ Хуона:

Ядро алгоритма:

  • Для каждого «шага разыменования» U (то есть, установите U = T, а затем U = *T, ...)
    1. , если есть методbar если тип получателя (тип self в методе) точно совпадает с U, используйте его ( a "методом по значению" )
    2. в противном случае добавьте одинauto-ref (взять & или &mut получателя) и, если получатель какого-либо метода соответствует &U, использовать его ( "метод autorefd" )

Ключ находится в «шагах разыменования»: U = *T означает let u = Deref::deref(t);, где u: U, t: T.Мы продолжаем делать это до тех пор, пока что-то больше не может быть разыменовано.

Следуя этому алгоритму для вызова s.chars() из вашего кода:

  1. Первый шаг разыменования (без разыменования):
    1. Можете ли вы позвонить String::chars(s)? Нет.
    2. А как насчет &String или &mut String? Нет.
  2. Второй шаг разыменования: <String as Deref>::Target = str, поэтому мы ищем методы str.let c: str = *s (при условии, что этот тип DST был разрешен);
    1. Можете ли вы позвонить str::chars(c)? Нет .
    2. Можете ли вы позвонить str::chars(&c)? Да!
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...