迭代器iter的find实现解析

本文解析了rcore代码中find()函数的工作原理,重点在于其接受闭包作为参数,该闭包用于判断元素是否满足条件。find()函数是短路的,一旦找到匹配项就停止执行。同时,讲解了check函数如何将FnMut类型的闭包转换为处理元组并返回ControlFlow的函数。
摘要由CSDN通过智能技术生成

 在学习rcore代码过程中突发好奇迭代器的find()原理

从源代码注释可知,find 根据闭包作为参数,然后bool类型,闭包捕捉迭代器的参数类型为迭代器成员类型

    /// Searches for an element of an iterator that satisfies a predicate.
    ///
    /// `find()` takes a closure that returns `true` or `false`. It applies
    /// this closure to each element of the iterator, and if any of them return
    /// `true`, then `find()` returns [`Some(element)`]. If they all return
    /// `false`, it returns [`None`].
    ///
    /// `find()` is short-circuiting; in other words, it will stop processing
    /// as soon as the closure returns `true`.
    ///
    /// Because `find()` takes a reference, and many iterators iterate over
    /// references, this leads to a possibly confusing situation where the
    /// argument is a double reference. You can see this effect in the
    /// examples below, with `&&x`.
    ///
    /// If you need the index of the element, see [`position()`].
    ///
    /// [`Some(element)`]: Some
    /// [`position()`]: Iterator::position
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// let a = [1, 2, 3];
    ///
    /// assert_eq!(a.iter().find(|&&x| x == 2), Some(&2));
    ///
    /// assert_eq!(a.iter().find(|&&x| x == 5), None);
    /// ```
    ///
    /// Stopping at the first `true`:
    ///
    /// ```
    /// let a = [1, 2, 3];
    ///
    /// let mut iter = a.iter();
    ///
    /// assert_eq!(iter.find(|&&x| x == 2), Some(&2));
    ///
    /// // we can still use `iter`, as there are more elements.
    /// assert_eq!(iter.next(), Some(&3));
    /// ```
    ///
    /// Note that `iter.find(f)` is equivalent to `iter.filter(f).next()`.
    #[inline]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[rustc_do_not_const_check]
    fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
    where
        Self: Sized,
        P: FnMut(&Self::Item) -> bool,
    {
        #[inline]
        fn check<T>(mut predicate: impl FnMut(&T) -> bool) -> impl FnMut((), T) -> ControlFlow<T> {
            move |(), x| {
                if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::Continue(()) }
            }
        }

        self.try_fold((), check(predicate)).break_value()
    }

以上源码主要难点在于:
1,predicate 类型为: FnMut(&Self::Item) -> bool

2,check 函数类型,输入参数为 predicate类型,返回类型为

FnMut((), T) -> ControlFlow<T>

也就是 check函数的原型是 将 FnMut(&Self::Item) -> bool转化为

FnMut((), &Self::Item) -> ControlFlow<&Self::Item>

fold函数是成员展开,如果配到true为则返回当前Item,  否则继续下一个成员展开

check函数的难点是函数原型

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值