我正在建立a library for generating the minimum perfect hash from a set of keys。这个想法是在不将完整数据集存储在内存中的情况下在线索引键。根据用户需求,skip_next()
可能不可用,我想回退使用next()
。尽管根据迭代器的速度,它可能会变慢,但它可以简化普通用户的工作。
我的想法是选择性地迭代迭代器生成的所有元素。这段代码可以正常工作,但是需要用户实现特征FastIteration
:
#[derive(Debug)]
struct Pixel {
r: Vec<i8>,
g: Vec<i8>,
b: Vec<i8>,
}
#[derive(Debug)]
struct Node {
r: i8,
g: i8,
b: i8,
}
struct PixelIterator<'a> {
pixel: &'a Pixel,
index: usize,
}
impl<'a> IntoIterator for &'a Pixel {
type Item = Node;
type IntoIter = PixelIterator<'a>;
fn into_iter(self) -> Self::IntoIter {
println!("Into &");
PixelIterator {
pixel: self,
index: 0,
}
}
}
impl<'a> Iterator for PixelIterator<'a> {
type Item = Node;
fn next(&mut self) -> Option<Node> {
println!("next &");
let result = match self.index {
0 | 1 | 2 | 3 => Node {
r: self.pixel.r[self.index],
g: self.pixel.g[self.index],
b: self.pixel.b[self.index],
},
_ => return None,
};
self.index += 1;
Some(result)
}
}
trait FastIteration {
fn skip_next(&mut self);
}
impl<'a> FastIteration for PixelIterator<'a> {
fn skip_next(&mut self) {
self.index += 1;
}
}
fn main() {
let p1 = Pixel {
r: vec![11, 21, 31, 41],
g: vec![12, 22, 32, 42],
b: vec![13, 23, 33, 43],
};
let mut index = 0;
let mut it = p1.into_iter();
loop {
if index == p1.r.len() {
break;
}
if index == 1 {
it.skip_next()
} else {
let val = it.next();
println!("{:?}", val);
}
index += 1;
}
}
如何基于特征next()
是否实现而使上述程序退回到使用普通的skip_next()
而不是FastIteration
?
fn fast_iterate<I>(objects: I)
where I: IntoIter + FastIteration { // should use skip_next() };
fn slow_iterate<I>(objects: I)
where I: IntoIter { // should NOT use skip_next(), use next() };
如上所述,一个人总是可以写两个单独的impl
,但是有可能合而为一吗?
此问题基于:
答案 0 :(得分:1)
您正在寻找不稳定功能专业化:
#![feature(specialization)]
#[derive(Debug)]
struct Example(u8);
impl Iterator for Example {
type Item = u8;
fn next(&mut self) -> Option<u8> {
let v = self.0;
if v > 10 {
None
} else {
self.0 += 1;
Some(v)
}
}
}
trait FastIterator: Iterator {
fn skip_next(&mut self);
}
impl<I: Iterator> FastIterator for I {
default fn skip_next(&mut self) {
println!("step");
self.next();
}
}
impl FastIterator for Example {
fn skip_next(&mut self) {
println!("skip");
self.0 += 1;
}
}
fn main() {
let mut ex = Example(0);
ex.skip_next();
let mut r = 0..10;
r.skip_next();
}