首页 > 解决方案 > 为什么 Iterator::filter 方法接受可变引用作为 self?

问题描述

的签名Iterator::filter

fn filter<P>(self, predicate: P) -> Filter<Self, P>
where
    Self: Sized,
    P: FnMut(&Self::Item) -> bool,

因为它self作为第一个参数,我假设我必须按值传递迭代器,从而将所有权转移到该函数。但是,我可以只用一个 ref mut 来调用它,并且代码会编译并运行。例如:

fn char_count(i: &mut impl Iterator<Item=char>, c: char) -> usize {
    i.filter(|&x| c == x).count()
}

我在这里想念什么?

标签: rustself

解决方案


这里的两个参数存在混淆。

self参数引用原始迭代器。也就是说,filter()将原始迭代器的任何内容移动到新Filter结构中,该结构获得该迭代器的所有权(Selfin Filter<Self, _>

predicateaFnMut因为它不需要是Fn。也就是说,as 提供的函数predicate允许修改它在执行时捕获的上下文。这是可能的,因为它调用它时它Filter本身并不借用。predicate如果是这样,predicate则必须是Fn(&Self::Item).

通过predicate引用获取迭代器的项目。注意签名中的印记FnMut(&Self::Item)


推荐阅读