Вопрос начинающего Rust: использование изменяемой или неизменяемой ссылки в цикле chars for-loop - PullRequest
0 голосов
/ 08 февраля 2020
  • нет ссылки и результат выполнения кода
fn main() {
    let str_value: String = "abc".to_string();

    let chars = str_value.chars();
    for char_value in chars {
        println!("char: {}", char_value);
    }
}
char: a
char: b
char: c
  • неизменяемая ссылка и результат выполнения кода
fn main() {
    let str_value: String = "abc".to_string();

    let chars = str_value.chars();
    for char_value in &chars {
        println!("char: {}", char_value);
    }
}
 --> question.rs:5:23
  |
5 |     for char_value in &chars {
  |                       -^^^^^
  |                       |
  |                       `&std::str::Chars<'_>` is not an iterator
  |                       help: consider removing 1 leading `&`-references
  |
  = help: the trait `std::iter::Iterator` is not implemented for `&std::str::Chars<'_>`
  = note: `std::iter::Iterator` is implemented for `&mut std::str::Chars<'_>`, but not for `&std::str::Chars<'_>`
  = note: required by `std::iter::IntoIterator::into_iter`
  • изменяемая ссылка и результат выполнения кода
fn main() {
    let str_value: String = "abc".to_string();

    let mut chars = str_value.chars();
    for char_value in &mut chars {
        println!("char: {}", char_value);
    }

    // why chars equal ""?
    assert_eq!(chars.as_str(), "");
}
char: a
char: b
char: c

Я запутался, как изменяемая ссылка работает в for-l oop, а неизменяемой - нет. Это итератор?
, и я просто нахожу, что после l oop ссылка chars относится к значению "".

1 Ответ

2 голосов
/ 08 февраля 2020

chars имеет тип Chars, который реализует ("является") итератор , элементы которого имеют тип char.

В Rust вы можете использовать for -loops для вещей, которые реализуют («являются») итератор .

Таким образом, ваш первый пример должен охватываться этим : Перебирает char s.

Второй пример не работает, потому что &chars имеет тип &Chars (заимствованная, не изменяемая ссылка), который не внедряет Iterator.

В третьем примере, однако, у вас есть &mut Chars, и это итератор :

impl<I: Iterator + ?Sized> Iterator for &mut I {
    type Item = I::Item;
    fn next(&mut self) -> Option<I::Item> { (**self).next() }
    // some details omitted
}

выше сказано: для любого типа I, который является Iterator и который может не удовлетворять ?Sized (все это верно для типа Chars), тип &mut I является Iterator, чьи повторяющиеся значения так же, как исходные итерированные типы (type Item = I::Item) и делегирует next (и некоторые другие методы) исходному итератору.

Таким образом, третий пример видит &mut Chars, знает, что Chars является * 104 7 *, и делает вывод, что тогда &mut Chars также является Iterator, который может использоваться в for -l oop.

as_str - в соответствии с его документация (см. пример там) дает вам оставшуюся (т. е. еще не повторенную) подстроку, поэтому после итерации она должна просто сказать "" (т. е. пустой), так как не осталось ничего для итерации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...