这个问题在这里已有答案:
在函数式编程语言中,集合上最原始/最基本的操作是同态 map
;它(大致) Collection[A] -> (A->B) -> Collection[B]
Rust系列似乎不支持这一点 . 我想这是因为它们是可变的集合;如果您已经在使用可变集合,则就地更新会更有效 .
我错过了一个单独的“不可变集合”库(比如Scala)吗?
怎么样的"in-place map"操作使用 A->B
将 Collection[A]
变成 Collection[B]
(与ML和Haskell不同,它实际上可以安全地做到这一点因为仿射类型!)甚至特殊情况 A=B
和就地 Map 需要 A->A
?
很难用搜索引擎来回答这个问题,因为所有的命中都涉及名词"map"(如 HashMap
) .
2 回答
要将容器映射到容器,请迭代并
collect()
:要在适当位置更改项目,请使用for循环和
iter_mut()
. 不建议在这种情况下使用迭代器链接,因为修改值会引入副作用 .Rust有一个
map()
函数,但它不是每个单独容器的一部分,而是特征Iterator(Rust特性与Haskell的类型类非常相似):Iterator:map() . 该特征包含许多有用的方法,其中许多方法对于FP程序员来说应该是熟悉的 .让我们看看
map()
在行动:map()
的类型是您所期望的:或者在Rust语法中:
这首先看起来更复杂,但它确实有意义,将来可能会更好 . 签名是
(self, f: F) -> Map<Self, F>
. 和:self
是Iterator
overSelf::Item
[比较:Iterator a
]F
是FnMut(Self::Item) -> B
[比较:(a -> b)
]Map<Self, F>
是Iterator
无论F
返回(B
)[比较Iterator b
]如果你想做一个就地
a -> a
map(意思是:没有chaning类型),你可以获得对每个元素的可变引用并进行更改 . 例:如果没有不安全的代码,目前无法执行更改类型的就地映射 . 部分原因是Rust的类型系统无法在编译时比较两种类型的大小(但它会改变) .