我需要实现方法iter
,它返回实现特征Iterator<Item = char>
的东西。但返回值将是不同的实现,具体取决于枚举变体。
这样的事情:
pub enum Class {
SingleChar(char),
Range(Range),
And(Vec<Class>),
Or(Vec<Class>),
}
impl Class {
pub fn iter(&self) -> Iterator<Item = char> {
match *self {
Class::SingleChar(c) => vec![c],
Class::Range(ref range) => range.iter(),
Class::And(ref classes) => {
let iter: Option<_> = classes.iter().fold(None, |iter, &class| {
match iter {
None => Some(class.iter()),
Some(iter) => Some(iter.merge(class.iter())),
}
});
Box::new(iter.unwrap())
},
Class::Or(ref classes) => {
let iter: Option<_> = classes.iter().fold(None, |iter, &class| {
match iter {
None => Some(class.iter()),
Some(iter) => Some(iter.interleave(class.iter())),
}
});
Box::new(iter.unwrap())
},
}
}
}
range.iter()
返回一个实现Iterator<Item=char>
的结构。
merge
和interleave
是itertools
方法,分别返回MergeAscend
和Interleave
(两者都实现Iterator<Item=char>
)
答案 0 :(得分:3)
使用静态调度无法做到这一点。在未装箱的抽象返回类型上有tracking RFC issue,但Rust还没有(我不确定它是否可以涵盖返回不同类型的用例)。因此,动态调度是可行的方法。
实际上,你非常接近。只需返回类型Box<Iterator<Item=char>>
并添加更多拳击:
pub fn iter(&self) -> Box<Iterator<Item=char>> {
match *self {
Class::SingleChar(c) => Box::new(Some(c).into_iter()),
Class::Range(ref range) => Box::new(range.iter()),
Class::And(ref classes) => {
let iter: Option<_> = classes.iter().fold(None, |iter, &class| {
match iter {
None => Some(Box::new(class.iter())),
Some(iter) => Some(Box::new(iter.merge(class.iter()))),
}
});
iter.unwrap()
},
Class::Or(ref classes) => {
let iter: Option<_> = classes.iter().fold(None, |iter, &class| {
match iter {
None => Some(Box::new(class.iter())),
Some(iter) => Some(Box::new(iter.interleave(class.iter()))),
}
});
iter.unwrap()
},
}
}
这应该有用。