5 个版本
0.1.4 | 2023年2月12日 |
---|---|
0.1.3 | 2023年2月12日 |
0.1.2 | 2023年2月11日 |
0.1.1 | 2023年2月11日 |
0.1.0 | 2023年2月11日 |
#12 in #read-only
每月 22 次下载
12KB
198 行
iter_view
Rust 有 IntoIterator
特性,用于从一个类型创建 Iterator
。 IntoIterator
消耗类型,许多类型提供 iter()
方法,从不可变引用创建 Iterator
而不消耗类型。但没有为 iter()
方法提供特性。
在大多数情况下,这种特性不是必需的,因为 iter()
方法返回的 Iterator
实现了 IntoIterator
特性。但考虑以下情况
trait Inspector<T> {
fn inspect(&self, v: &T);
}
inspect()
方法接受 T
的不可变引用,而 T
不是 Copy
类型。如果为任何对象实现 Inspector
可以转换为 Iterator
,我们可以编写如下代码
impl<T, I> Inspector<T> for I
where
I: IntoIterator<Item = T>,
T: std::fmt::Debug,
{
fn inspect(&self, v: &T) {
for item in self {
println!("{:?}", item);
}
}
}
但是 IntoIterator
特性会消耗类型,编译器不会让它消失。
如果我们为切片实现 Inspector
impl<T: std::fmt::Debug> Inspector<T> for [T] {
fn inspect(&self, v: &T) {
for item in self {
println!("{:?}", item);
}
}
}
不会工作,除非我们将 Inspector
特性修改为允许无尺寸类型
trait Inspector<T: ?Sized> {
fn inspect(&self, v: &T);
}
无尺寸类型是有毒的,使用起来会造成很多麻烦,我们不想使用它。
Vec<T>
支持非常容易地转换为切片,但许多其他类型不支持它,例如 HashMap
、LinkedList
,切片版本无法涵盖所有情况。
我们无法将 Iterator
传递给 inspect()
方法,因为 Iterator
是一个可变对象,而 inspect()
需要不可变引用,这使得它无法工作。
iter_view
包提供了 IterView
特性,它与 IntoIterator
类似,但它不会消耗类型
pub trait IterView<'a> {
type Item: 'a;
type Iter: Iterator<Item = &'a Self::Item>;
fn iter(&'a self) -> Self::Iter;
}
使用 IterView
特性,我们可以为任何实现了 IterView
的类型实现 Inspector
impl<T, I> Inspector<T> for I
where
I: IterView<Item = T>,
T: std::fmt::Debug,
{
fn inspect(&self, v: &T) {
for item in self.iter() {
println!("{:?}", item);
}
}
}
许可证:MIT OR Apache-2.0