在这个例子中,NoGood是pub,AtomWord是私有的.
我想导出一个IntoIterator的实例,但我不能,因为IntoIter的这个巨大的类型定义包含对AtomWord的引用.
我意识到我可以创建一个Iterator包装器,只是将调用传递给底层迭代器,但这是很多样板.我想不出有任何方法可以使包装类通用(不破坏目的,即隐藏AtomWord类型).
impl <'a> IntoIterator for &'a NoGood {
type Item = Literal;
type IntoIter = FilterMap<slice::Iter<'a, AtomWord>, fn(&AtomWord) -> Option<Literal>>;
fn into_iter(self) -> Self::IntoIter {
(&self.lits).into_iter().filter_map(as_opt_lit)
}
}
最佳答案 不,您无法在公共方法中隐藏私有类型.它是公开的,这意味着人们需要看到它.
作为delnan mentions,包装器结构对于迭代器是常见的.它也恰好没有运行时成本:
struct Iter<'a>(FilterMap<slice::Iter<'a, AtomWord>, fn(&AtomWord) -> Option<Literal>>);
impl<'a> Iterator for Iter<'a> {
type Item = Literal;
fn next(&mut self) -> Option<Literal> {
self.0.next()
}
}
impl<'a> IntoIterator for &'a NoGood {
type Item = Literal;
type IntoIter = Iter;
fn into_iter(self) -> Self::IntoIter {
Iter((&self.lits).into_iter().filter_map(as_opt_lit))
}
}
而作为ker mentions,你可以装箱.这节省了程序员的打字时间,但是以运行时内存分配为代价:
impl<'a> IntoIterator for &'a NoGood {
type Item = Literal;
type IntoIter = Box<Iterator<Item = Literal>>;
fn into_iter(self) -> Self::IntoIter {
Box::new((&self.lits).into_iter().filter_map(as_opt_lit))
}
}
请注意,我没有尝试编译任何这些,因为您没有提供MCVE,因此您的代码无论如何都不会编译.