Почему предикаты для FnMut итератора Rust, а не Fn? - PullRequest
1 голос
/ 19 октября 2019

Глядя на предикаты, такие как skip_while и take_while, они

skip_while<P>(self, predicate P) -> ...
  where Self: Sized, P: FnMut(&Self::Item) -> bool;

Если предикат просто возвращает истину или ложь, а не изменяет значения, почему это должно быть FnMut а не Fn (как Fn(&Self::Item) -> bool)?

1 Ответ

3 голосов
/ 19 октября 2019

Mut в FnMut означает, что предикат может иметь изменяемое состояние. О параметрах ничего не говорится.

Дополнительно, FnMut - это супер-черта Fn, поэтому вы также можете передать Fn, где FnMut принято.

В качестве глупого примера рассмотрим это замыкание, которое хранит состояние (следовательно, FnMut, но не Fn), но не может изменять элементы в итераторе:

fn main() {
    let v = vec![1, 2, 3, 4, 0, 5, 6, 7];

    println!("{:?}", v.iter().skip_while(|&&v| v != 0).collect::<Vec<_>>());

    let mut state = false;
    let one_after_zero = |&&v: &&u32| {
        if state {
            false
        } else if v == 0 {
            state = true;
            true
        } else {
            true
        }
    };

    println!("{:?}", v.iter().skip_while(one_after_zero).collect::<Vec<_>>());
}

( Постоянная ссылка надетская площадка )

Выход:

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