我正在尝试实现一个函数,它将为几个相关的2D数组(总是具有相同的大小)在整个可能的索引范围内构造迭代器。然而,编译器给了我一个错误,说我传递给map
的闭包没有实现Fn
,只有FnMut
。这是我的原始代码:
pub fn get_index_iterator(&self) -> Map<Range<usize>, impl Fn(usize) -> (usize, usize)> {
(0usize..(self.width * self.height))
.map(|idx| -> (usize, usize) {
(idx % self.width, idx / self.width)
}
)
}
字符串
为了弄清楚发生了什么,我最终尝试用下面的代码替换它:
pub fn get_index_iterator(&self) -> Map<Range<usize>, impl Fn(usize) -> (usize, usize)> {
(0usize..(self.width * self.height))
.map(|idx| -> (usize, usize) {
(0usize, 0usize)
}
)
}
型
只是想看看错误是否会更改为更有用的内容,但它没有更改,错误仍然存在
expected a `std::ops::Fn<(usize,)>` closure, found `[closure@src\lib.rs:33:18: 33:41]`
the trait `std::ops::Fn<(usize,)>` is not implemented for closure `[closure@src\lib.rs:33:18: 33:41]`
`[closure@src\lib.rs:33:18: 33:41]` implements `FnMut`, but it must implement `Fn`, which is more general
型
对于这两个版本。我不明白一个返回常量而不做任何其他事情的闭包怎么可能改变它的环境状态。我错过了什么?
1条答案
按热度按时间ezykj2lf1#
我不知道为什么会发生这种情况,但是如果你让闭包成为它自己的变量,它在两种情况下都能工作。
字符串
您需要
+ '_
,因为它捕获了self
,但它仍然是一个Fn
,因为它应该是。因此,您正确地认为此闭包应该作为Fn
工作。可能是map
以某种方式降低了闭包的级别,但我不知道如何将其作为变量传递。除此之外,您还可以将其写成
impl Iterator
,以完全避免这种情况。这是最好的选择,因为如果您希望稍后对其进行优化,则可以更改迭代器类型,而不会破坏API。它也更短。无论如何,您都需要mut
来调用Map
上的next
,因此使用闭包Fn
而不是FnMut
不会带来任何好处。型
下面是一个显示相同行为的较短版本。
型