gpt4 book ai didi

iterator - 在嵌套迭代器中指定生命周期以进行展平

转载 作者:行者123 更新时间:2023-11-29 07:57:37 25 4
gpt4 key购买 nike

我正在编写一个函数,它应该采用几个向量并将它们的笛卡尔积(它们的所有对组合)作为行优先顺序的向量。换句话说,如果我有

let x_coords = vec![1, 2, 3];
let y_coords = vec![4, 5, 6];

我要生产

vec![ [1,4], [1,5], [1,6], [2,4], [2,5], [2,6], [3,4], [3,5], [3,6] ]

对于 .flat_map() 来说,这似乎是一项完美的工作:

fn main() {
let x_coords = vec![1, 2, 3];
let y_coords = vec![4, 5, 6];

let coord_vec: Vec<[isize; 2]> =
x_coords.iter().map(|&x_coord| {
y_coords.iter().map(|&y_coord| {
[x_coord, y_coord]
})
}).flat_map(|s| s).collect();

// Expecting to get: vec![ [1,4], [1,5], [1,6], [2,4], [2,5], [2,6], [3,4], [3,5], [3,6] ]
println!("{:?}", &coord_vec);
}

但这行不通,因为 &x_coord 的生命周期不够长。根据编译器的说法,它最终位于 y_coords map 内,然后再也不会退出。

我尝试在闭包中使用 .clone()move,但编译器以多个 Note 的形式进行了冗长且不清楚的讲授: 行。

flat_map 我是完全偏离了基础,还是可以保存它?

最佳答案

解决方案

你们真的很亲密!这有效:

let coord_vec: Vec<_> = x_coords.iter()
.flat_map(|&x_coord| {
y_coords.iter().map(move |&y_coord| {
// ^^^^
[x_coord, y_coord]
})
})
.collect();

我唯一添加的是内部闭包前面的 move 关键字。为什么?下面让我们试着了解编译器在想什么!

但有几点要注意:

  • 我将 map 重命名为 flat_map 并删除了第二个 flat_map 调用...你让你的生活变得更加复杂; -)
  • 我省略了coord_vec的部分类型注解,因为没必要

解释

类型x_coordi32(或任何其他整数)。不是引用或任何东西,而是直接的值(value)。这意味着 x_coord 由封闭函数拥有,它恰好是一个闭包,特别是传递给 flat_map 的“外部”闭包。因此 x_coord 只存在于闭包内,而不是更长。这就是编译器告诉你的。到目前为止一切顺利。

当您定义第二个闭包(“内部”闭包)时,您可以访问环境,特别是 x_coord。现在的重要问题是:闭包如何访问它的环境?它可以通过不可变引用、可变引用和值来实现。 Rust 编译器确定需要什么样的环境访问权限,并选择有效的“最少侵入”选项。让我们看看你的代码:编译器发现闭包只需要不变地借用环境(因为 i32Copy 因此闭包可以转换它的 &i32 轻松转换为 i32

但在这种情况下,编译器的推理是错误的!借用其环境的闭包导致有限的生命周期。在这种情况下,我们需要闭包比它能活得更久,因此会出现错误。

通过添加move,我们强制编译器按值将环境传递给闭包(转移所有权)。这样闭包就不会借用任何东西并且可以永远存在(满足 'static)。

关于iterator - 在嵌套迭代器中指定生命周期以进行展平,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41308549/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com