如何将一系列迭代器应用于数据?

How to apply a series of iterators to data?

我正在通过构建一些基本的遗传学功能来修补 Rust,例如读取包含 DNA 序列的文件、将其转录为 RNA、将其翻译为氨基酸序列等。

我希望每个转换都接受和 return 迭代器。这样我就可以将它们串在一起(比如 dna.transcribe().traslate()...)并且只在必要时收集,这样编译器就可以优化整个转换链。我是一名来自 Scala/Spark 的数据科学家,所以这种模式很有意义,但我不确定如何在 Rust 中实现它。

我读过 this article about returning iterators 但最终的解决方案似乎是使用 trait 对象(可能会对性能产生很大影响),或者使用关联结构的手动迭代器(这允许我 return 一个迭代器,是的,但我不明白它如何允许我编写一个也 接受 迭代器的转换)。

这里有什么一般的架构建议吗?

(仅供参考,到目前为止我的代码是 available here,但我觉得我没有按照惯用方式使用 Rust,因为 a. 仍然不能完全编译 b. 这种惰性链接操作模式导致了出乎意料的复杂和混乱的代码,每晚只能在 Rust 上运行。)

迭代器适配器用于执行其他方式无法轻易表达的操作。根据您对它们的解释,您的两个示例 .translate().transcribe() 可以简化为以下内容:

dna
    .map(|x| x.translate())
    .map(|x| x.transcribe())

// or

dna
    .map(|x| x.translate().transcribe())

但是,如果您打算设计自己的迭代器,则以下方法应该可行:

struct Transcriber<I: Iterator<Item = Dna>> {
    inner: I
}

impl<I: Iterator<Item = Dna>> Iterator for Transcriber<I> {
    type Item = TranscribedDna;
    fn next(&mut self) -> Option<Self::Item> {
        self.next().map(|x| x.transcribe())
    }
}

// Extension trait to add the `.transcribe` method to existing iterators
trait TranscribeIteratorExt: Iterator<Item = Dna> {
    fn transcribe(self) -> Transcriber<Self>;
}

impl<I: Iterator<Item = Dna>> TranscriberIteratorExt for I {
    fn transcribe(self) -> Transcriber<Self> {
        Transcriber { inner: self }
    }
}

那你就可以使用

dna
    .transcribe() // yields TranscribedDna