如何将一系列迭代器应用于数据?
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
我正在通过构建一些基本的遗传学功能来修补 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