16 个版本
0.1.7 | 2023 年 4 月 4 日 |
---|---|
0.1.7-rc1 | 2023 年 4 月 2 日 |
0.1.6 | 2022 年 8 月 8 日 |
0.1.5 | 2022 年 7 月 22 日 |
0.0.0 | 2022 年 5 月 26 日 |
185 in Rust 模式
33,490 个月下载量
用于 7 个crate(5 个直接使用)
88KB
1.5K SLoC
::借款-迭代器
稳定 Rust 中的完全泛型 LendingIterator
。
-
这个模式以前被称为
StreamingIterator
,但由于Stream
出现了(作为async/.await
版本的Iterator
,即AsyncIterator
),因此更倾向于采用 借款 命名约定。- (这甚至可能更为相关,因为你可以有一个借款
LendingIterator
借款impl Future
,这将实际上使其成为另一种AsyncIterator
的风味,但不是Stream
变体)。
- (这甚至可能更为相关,因为你可以有一个借款
-
为了说明背景,这个crate是其他crate(如)的泛化
它们将借款
Item
类型分别硬编码为&_
和Result<&_, _>
。这个crate没有硬编码这样的依赖类型,因此包含了两个这些特性和无限更多!
-
主要,它允许借款
&mut _
Item
,这意味着它可以处理臭名昭著的windows_mut()
模式!
示例
点击隐藏
windows_mut()
!
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
封闭的返回类型。实际上,如果我们仅让类型推断来完成这项工作,它将无法知道哪些生命周期将固定/绑定到调用站点捕获,以及哪些将绑定到迭代器的“lending”(高阶返回类型)特性。有关更多信息,请参阅
::higher-order-closure
。
LendingIterator
适配器
请参阅 lending_iterator::adapters
。
附加:高阶类型(HKT)
有关它们的信息,请参阅 higher_kinded_types
。
实际使用:对键 lending 模式完全泛型的 .sort_by_key()
如在此 6 年前的 issue 中所述
使用此 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);
}
依赖项
~1.5MB
~38K SLoC