【问题标题】:Hide private type in exported signature在导出的签名中隐藏私有类型
【发布时间】:2015-10-31 23:23:24
【问题描述】:

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

【问题讨论】:

  • 实际上,如果 Rust 有类似 GeneralizedNewtypeDeriving 的东西,包装类解决方案会非常好。是吗?
  • 因为这里只有一个特征和一种方法需要实现,所以包装器解决方案似乎被接受(虽然不理想,但显然)。
  • 或者将迭代器装箱:type IntoIter = Box&lt;Iterator&lt;Item=Literal&gt;&gt;
  • @dspyz 很遗憾,它还没有这个功能(还没有?)。不过,我很想在一般委托和包装器结构方面有所帮助。
  • 这个问题talks a bit more关于GeneralizedNewtypeDeriving

标签: types rust private encapsulation public


【解决方案1】:

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

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

【讨论】:

  • 迭代器有很多方法。为了获得最佳性能,我不应该实现所有这些吗?至少我应该有 size_hint,不是吗?
  • @dspyz 好问题! Right now,标准库中没有多少类型可以有效地实现迭代器方法本身。但是,我认为您是对的,为了获得更好的性能,您会将所有这些方法转发到内部字段。我认为这就是您的 GeneralizedNewtypeDeriving 将提供的帮助...
猜你喜欢
  • 1970-01-01
  • 2018-06-05
  • 2012-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多