隐藏导出签名中的私有类型

时间:2015-08-08 16:11:49

标签: types rust private encapsulation public

在此示例中,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)
    }
}

1 个答案:

答案 0 :(得分:2)

不,您无法在公共方法中隐藏私有类型。它是公开的,这意味着人们需要看到它。

作为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,因此您的代码无论如何都不会编译。