[英]How to use std::iter::Iterator::map for tree-like structures in Rust?
据我了解,将函数应用于 Rust 结构的每个元素的惯用方法是实现IntoIterator
和FromIterator
并使用map
和collect
。 像这样:
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
函数应用于结构的每个元素的惯用方法是实现IntoIterator
和FromIterator
这并不完全正确。 惯用的方法是提供一个迭代器,但您不必实现这些特征。
以&str
为例:没有一种规范的方式来迭代字符串。 你可以迭代它的字节或它的字符,因此它没有实现IntoIterator
但有两个方法bytes
和chars
返回不同类型的迭代器。
一棵树将是类似的:没有一种方法可以迭代一棵树,因此它可以有一个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.