我正尝试在二维网格上实现迭代器,如下所示(这是对更为复杂的设置的简化):
struct Grid {
width: usize,
height: usize,
}
impl Grid {
fn new(width: usize, height: usize) -> Grid {
Grid { width, height }
}
fn iter<'a>(&'a self) -> &'a impl Iterator<Item = (usize, usize)> {
let i = (0..self.height).flat_map(|y: usize| (0..self.width).map(move |x| (x, y)));
&i
}
}
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/lib.rs:12:43
|
12 | let i = (0..self.height).flat_map(|y: usize| (0..self.width).map(move |x| (x, y)));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the method body at 11:13...
--> src/lib.rs:11:13
|
11 | fn iter<'a>(&'a self) -> &'a impl Iterator<Item = (usize, usize)> {
| ^^
= note: ...so that the types are compatible:
expected &&Grid
found &&'a Grid
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that return value is valid for the call
--> src/lib.rs:11:34
|
11 | fn iter<'a>(&'a self) -> &'a impl Iterator<Item = (usize, usize)> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
我不知道如何将适当的生存期引用返回给迭代器。我了解迭代器的生命周期不得超过基础Grid
结构的生命周期。
答案 0 :(得分:3)
返回类型不能为引用。诀窍是为返回类型添加一个生存期说明符。另外,两个闭包都必须具有move
才能捕获self
和y
的所有权。
fn iter<'a>(&'a self) -> impl Iterator<Item = (usize, usize)> + 'a {
(0..self.height).flat_map(move |y| (0..self.width).map(move |x| (x, y)))
}
答案 1 :(得分:3)
这里没有理由维护对原始结构的任何引用,因为所有封闭值都实现了Copy
。您只需要从该结构中提取height
和width
,然后进行复制:
fn iter(&self) -> impl Iterator<Item = (usize, usize)> {
let Self { height, width } = *self;
(0..height).flat_map(move |y| (0..width).map(move |x| (x, y)))
}