4 个版本 (2 个稳定版)
1.0.1 | 2023 年 5 月 23 日 |
---|---|
1.0.0 | 2023 年 5 月 22 日 |
0.2.0 | 2020 年 9 月 28 日 |
0.1.0 | 2020 年 9 月 22 日 |
#480 in Rust 模式
每月 1,760 次下载
在 cargo-sonar 中使用
16KB
124 行
dyn-iter
这个小巧的包可以帮助您在需要将 Iterator
作为特例对象包装时简化代码。
想象一下以下这样的特例。
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Color {
Red,
Green,
Blue,
White,
Black,
}
trait Colors<'a> {
type ColorsIter: Iterator<Item = Color> + 'a;
fn colors(&'a self) -> Self::ColorsIter;
}
作为实现者,您有一个 struct Flag
,其外观如下。
# use std::collections::HashSet;
# #[derive(Debug, Clone, Copy, PartialEq, Eq)]
# enum Color {
# Red,
# Green,
# Blue,
# White,
# Black,
# }
struct Flag {
pub primary_colors: HashSet<Color>,
pub secondary_colors: HashSet<Color>,
}
您可能实现 Colors
,外观如下
# use std::collections::HashSet;
# use dyn_iter::{DynIter, IntoDynIterator as _};
# #[derive(Debug, Clone, Copy, PartialEq, Eq)]
# enum Color {
# Red,
# Green,
# Blue,
# White,
# Black,
# }
# struct Flag {
# pub primary_colors: HashSet<Color>,
# pub secondary_colors: HashSet<Color>,
# }
# trait Colors<'a> {
# type ColorsIter: Iterator<Item = Color> + 'a;
# fn colors(&'a self) -> Self::ColorsIter;
# }
impl<'a> Colors<'a> for Flag {
type ColorsIter = ???;
fn colors(&'a self) -> Self::ColorsIter {
self.primary_colors
.iter()
.chain(&self.secondary_colors)
.filter(|color| **color != Color::Black)
.copied()
}
}
在上述实现中,定义关联类型 ColorsIter
可能会很困难。 DynIter
应该能简化您的生活,因为您可以只需编写以下实现。
# use std::collections::HashSet;
# use dyn_iter::{DynIter, IntoDynIterator as _};
# #[derive(Debug, Clone, Copy, PartialEq, Eq)]
# enum Color {
# Red,
# Green,
# Blue,
# White,
# Black,
# }
# struct Flag {
# pub primary_colors: HashSet<Color>,
# pub secondary_colors: HashSet<Color>,
# }
# trait Colors<'a> {
# type ColorsIter: Iterator<Item = Color> + 'a;
# fn colors(&'a self) -> Self::ColorsIter;
# }
impl<'a> Colors<'a> for Flag {
type ColorsIter = DynIter<'a, Color>;
fn colors(&'a self) -> Self::ColorsIter {
self.primary_colors
.iter()
.chain(&self.secondary_colors)
.filter(|color| **color != Color::Black)
.copied()
.into_dyn_iter()
}
}
在幕后,DynIter<'iter, V>
只是在一个 Box<dyn Iterator<Item = V> + 'iter>
的基础上进行包装。
关于这个包为什么存在的更多细节,请阅读这篇 博客文章。