【问题标题】:Return Iterator of an array wrapped in an Option返回包含在选项中的数组的迭代器
【发布时间】:2021-05-08 23:59:53
【问题描述】:

我试图从传递给filter_map 的闭包中返回Option 中数组的数组迭代器,以便之后我可以将其展平。 不幸的是,rustc 产生以下错误:

cannot return value referencing local variable `res`

returns a value referencing data owned by the current function
main.rs(3, 5): returns a value referencing data owned by the current function
main.rs(3, 10): `res` is borrowed here

最简单的例子:

fn demo<'a>() -> Option<impl Iterator + 'a> {
    let res = [1,2];
    Some(res.into_iter())
}

虽然我正在尝试制作的完整代码是这样的:

fn generate_next<'a>(prev: &'a [u32]) -> impl Iterator + 'a {

    let mut counter = 1_u32;

    prev.windows(2).filter_map(move |window| {
        
        if window[0] == window[1] {
            counter+=1;
            None
        } else {
            let res = [counter, window[0]];
            counter=1;
            Some(res.into_iter())
        }
    }).flatten()
}

两者都对Some(...) 部分产生相同的错误。

如果我理解正确,代码应该可以工作,因为into_iter() 方法会消耗数组并从中生成一个迭代器。 Some 然后应该通过移动获得迭代器的所有权。为什么rustc会认为我在这里借res

我也对实现generate_next 函数的其他方式持开放态度。

【问题讨论】:

  • 您期望'a 生命周期在较短的示例中实现什么?
  • 错误必须相同,删除这些生命周期参数会产生不同的错误。

标签: arrays rust iterator lifetime borrow-checker


【解决方案1】:

在数组上调用into_iter() 产生与调用iter() 相同的结果,即引用迭代器。这是 Rust 标准库中的一个不幸的陷阱。

您可以通过使用std::iter::once 创建counterwindow[0] 的迭代器,然后将它们一起使用chain 来完成您想要的操作:

fn generate_next<'a>(prev: &'a [u32]) -> impl Iterator + 'a {
    let mut counter = 1_u32;

    prev.windows(2)
        .filter_map(move |window| {
            if window[0] == window[1] {
                counter += 1;
                None
            } else {
                let counter_iter = std::iter::once(counter);
                let window_iter = std::iter::once(window[0]);
                counter = 1;
                Some(counter_iter.chain(window_iter))
            }
        })
        .flatten()
}

playground

【讨论】:

  • 可能应该在回答之前检查是否有欺骗性。每周至少有一次。
  • 似乎我的实现中仍然存在一些错误,所以我无法确认它现在是否真的有效,但它似乎是一个可能的解决方案。
猜你喜欢
  • 1970-01-01
  • 2012-12-07
  • 2015-02-22
  • 2019-02-12
  • 1970-01-01
  • 2020-10-23
  • 1970-01-01
  • 2018-06-14
  • 1970-01-01
相关资源
最近更新 更多