#lending #iterator #proc-macro #stable #hkt #back-end

lending-iterator-proc_macros

内部:::lending_iterator 的 proc-macro 后端

14 个版本

0.1.7 2023 年 4 月 4 日
0.1.7-rc12023 年 4 月 2 日
0.1.6 2022 年 8 月 8 日
0.1.5 2022 年 7 月 22 日

1724过程宏

Download history 7649/week @ 2024-03-13 7379/week @ 2024-03-20 5027/week @ 2024-03-27 7185/week @ 2024-04-03 6933/week @ 2024-04-10 10530/week @ 2024-04-17 15035/week @ 2024-04-24 13631/week @ 2024-05-01 13634/week @ 2024-05-08 17833/week @ 2024-05-15 16746/week @ 2024-05-22 19083/week @ 2024-05-29 15684/week @ 2024-06-05 15021/week @ 2024-06-12 16694/week @ 2024-06-19 19363/week @ 2024-06-26

69,866 每月下载量
用于 7 个 crate(通过 lending-iterator

Zlib OR MIT OR Apache-2.0

6KB
97 行代码(不含注释)

::借出-迭代器

Repository Latest version Documentation MSRV unsafe forbidden License CI

稳定 Rust 中的完全泛型 LendingIterator

  • 此模式以前被称为 StreamingIterator,但由于 Stream 的出现(作为 Iterator 的异步版本,即 AsyncIterator),现在更合适使用 借出 命名约定。

    • (这甚至可能更加相关,因为你可以有一个借出 LendingIteratorimpl Future,这将有效地使其成为另一种 AsyncIterator 的风味,但不是 Stream 变体)。
  • 为了说明,这个 crate 是其他 crate 的泛化,例如

    它们将借出 Item 类型分别硬编码为 &_Result<&_, _>

    这个 crate 不硬编码这样的依赖类型,因此涵盖了 两个 这样的特性,以及更多无限的可能性!

  • 主要,它允许借出 &mut _ Item,这意味着它可以处理臭名昭著的 windows_mut() 模式!

示例

点击隐藏

WindowsMut()!

use ::lending_iterator::prelude::*;

let mut array = [0; 15];
array[1] = 1;
// Cumulative sums are trivial with a `mut` sliding window,
// so let's showcase that by generating a Fibonacci sequence.
let mut iter = array.windows_mut::<3>();
while let Some(&mut [a, b, ref mut next]) = iter.next() {
    *next = a + b;
}
assert_eq!(
    array,
    [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377],
);

使用便捷的 from_fn 构造函数创建自己的版本

  • (或者使用 FromFn 的变体以享受“命名参数”)
use ::lending_iterator::prelude::*;

let mut array = [0; 15];
array[1] = 1;
// Let's hand-roll our iterator lending `&mut` sliding windows:
let mut iter = {
    let mut start = 0;
    lending_iterator::FromFn::<HKT!(&mut [u16; 3]), _, _> {
        state: &mut array,
        next: move |array| {
            let to_yield =
                array
                    .get_mut(start..)?
                    .get_mut(..3)?
                    .try_into() // `&mut [u8] -> &mut [u8; 3]`
                    .unwrap()
            ;
            start += 1;
            Some(to_yield)
        },
        _phantom: <_>::default(),
    }
};
while let Some(&mut [a, b, ref mut next]) = iter.next() {
    *next = a + b;
}
assert_eq!(
    array,
    [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377],
);
  • 其中那个 HKT!(&mut [u16; 3]) 是一个 高阶 类型参数,必须 进行turbofishing 才能让泛型上下文正确地确定 next 闭包的返回类型。

    事实上,如果我们只让类型推断来完成这项工作,它将无法知道哪些生命周期会固定/绑定到调用站点捕获,以及哪些会绑定到迭代器的“借用性”(高阶返回类型)。有关此信息的更多信息,请参见::higher-order-closure

LendingIterator 适配器

请参阅lending_iterator::adapters


额外内容:高阶类型 (HKT)

请参阅higher_kinded_types 了解它们的相关内容。

实际应用:完全泛型于键借用模式的 .sort_by_key()

如本 6 年前的问题 所述

可以使用这个crate的HKT API轻松提供此类API

点击显示
use ::lending_iterator::higher_kinded_types::{*, Apply as A};

fn slice_sort_by_key<Key, Item, KeyGetter> (
    slice: &'_ mut [Item],
    mut get_key: KeyGetter,
)
where
    Key : HKT, // "Key : <'_>"
    KeyGetter : for<'item> FnMut(&'item Item) -> A!(Key<'item>),
    for<'item>
        A!(Key<'item>) : Ord
    ,
{
    slice.sort_by(|a, b| Ord::cmp(
        &get_key(a),
        &get_key(b),
    ))
}

// ---- Demo ----

struct Client { key: String, version: u8 }

fn main ()
{
    let clients: &mut [Client] = &mut [];

    // Error: cannot infer an appropriate lifetime for autoref due to conflicting requirements
    // clients.sort_by_key(|c| &c.key);

    // OK
    slice_sort_by_key::<HKT!(&str), _, _>(clients, |c| &c.key);

    // Important: owned case works too!
    slice_sort_by_key::<HKT!(u8), _, _>(clients, |c| c.version);
}


lib.rs:

该crate不打算直接使用。请使用 https://docs.rs/lending-iterator。

依赖项

~1.5MB
~35K SLoC