繁体   English   中英

如何在 Rust 中将 std::iter::Iterator::map 用于树状结构?

[英]How to use std::iter::Iterator::map for tree-like structures in Rust?

据我了解,将函数应用于 Rust 结构的每个元素的惯用方法是实现IntoIteratorFromIterator并使用mapcollect 像这样:

enum F<A> {
    // fields omitted
}

impl<A> IntoIterator for F<A> {
    // implementation omitted
}

impl<A> FromIterator<A> for F<A> {
    // implementation omitted
}

fn mapF<A, B>(x : F<A>, f) -> F<B> 
    where f : Fn(A) -> B 
{
    x.into_iter().map(f).collect()
}

然而,似乎不可能为树实现FromIterator ,因为有多种方法可以将一系列值组织到树中。 有没有办法解决这个问题?

在 Rust IntoIterator函数应用于结构的每个元素的惯用方法是实现IntoIteratorFromIterator

这并不完全正确。 惯用的方法是提供一个迭代器,但您不必实现这些特征。

&str为例:没有一种规范的方式来迭代字符串。 你可以迭代它的字节或它的字符,因此它没有实现IntoIterator但有两个方法byteschars返回不同类型的迭代器。

一棵树将是类似的:没有一种方法可以迭代一棵树,因此它可以有一个depth_first_search方法返回一个DepthFirstSearch迭代器和一个breadth_first_search方法返回一个BreadthFirstSearch迭代器。

类似地, String可以从&str的迭代器或char的迭代器构造,因此String实现了FromIterator<&str>FromIterator<char> ,但它没有实现FromIterator<u8>因为随机字节不太可能形成有效的 UTF- 8串。

也就是说,集合与其迭代器之间并不总是一对一的关系。


并使用 […] collect

这(大部分)是不正确的。 收集不是使用迭代器的好方法,除非您真的想在之后使用收集的结果。 如果只想执行一个迭代器的效果,使用for_each方法的for

您可以在迭代器中包含有关树结构的信息,例如

impl F {
    pub fn path_iter(self) -> impl Iterator<Iter=(TreePath, A)> { ... }
    // rest of impl
}

impl<A> FromIterator<(TreePath, A)> for F<A> {
    // implementation omitted
}

fn mapF<A, B>(x : F<A>, f) -> F<B> 
    where f : Fn(A) -> B 
{
    x.path_iter().map(|pair| (pair.0, f(pair.1))).collect()
}

使用TreePath特定于您的树的类型。 可能更好地表示不是路径本身而是如何移动到下一个节点。

我最初建议使用Item = (TreePath, A)实现IntoIterator但进一步认为默认迭代器仍应具有Item = A

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM