types - 在导出的签名中隐藏私有(private)类型

标签 types rust private encapsulation public

在这个例子中,NoGood是酒吧,AtomWord是私有(private)的。

我想导出 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)
    }
}

最佳答案

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

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

关于types - 在导出的签名中隐藏私有(private)类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31895960/

相关文章:

Java注释处理器: javax.validation.constraints.过去的注释更改了字段类型

c - 如何使用 OpenSSL 生成 RSA 私钥?

file - 使用 JSP/Tomcat 私下提供文件?

rust - 如何阻止子进程的标准输入并忽略其标准输出?

performance - 为什么XOR比OR快得多?

C++ 20?模块 - 不导出私有(private)

haskell - 我可以键入部分记录吗?

types - Elasticsearch:有没有办法将对象字段的所有(可能是动态的)子字段声明为字符串?

Java transient 变量类型必须知道序列化?

rust - 我不了解切片和引用(使用rust )之间的区别