我试图从创建每个元素的仿函数创建一个二维矩阵,并将其存储为一个平面Vec(每行连接).
我使用嵌套map(实际上是a flat_map和嵌套map)来创建每一行并连接它.这是我尝试过的:
fn make<T, F>(n: usize, m: usize, f: F) -> Vec<T>
where
F: Fn(usize, usize) -> T,
{
(0..m).flat_map(|y| (0..n).map(|x| f(x, y))).collect()
}
fn main() {
let v = make(5, 5, |x, y| x + y);
println!("{:?}", v);
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,我在编译期间遇到错误:
error[E0597]: `y` does not live long enough
--> src/main.rs:5:45
|
5 | (0..m).flat_map(|y| (0..n).map(|x| f(x, y))).collect()
| --- ^ - - borrowed value needs to live until here
| | | |
| | | borrowed value only lives until here
| | borrowed value does not live long enough
| capture occurs here
Run Code Online (Sandbox Code Playgroud)
如何在嵌套映射中使用闭包?我通过使用单个地图0..n*m解决了这个问题,但我仍然对答案感兴趣.
在你的情况下,内部闭包|x| f(x,y)是一个借用闭包,它通过引用获取其环境(y和f).
方式.flat_map(..)有效,它禁止您保留引用y,而不是来自外部范围.因此,我们需要让您的闭包按值获取其环境,这不是一个问题,y因为usize它是Copy:
(0..m).flat_map(|y| (0..n).map(move |x| f(x, y))).collect()
Run Code Online (Sandbox Code Playgroud)
但是,现在又出现了另一个问题:
error[E0507]: cannot move out of captured outer variable in an `FnMut` closure
--> src/main.rs:5:36
|
1 | fn make<T, F>(n: usize, m: usize, f: F) -> Vec<T>
| - captured outer variable
...
5 | (0..m).flat_map(|y| (0..n).map(move |x| f(x,y))).collect()
| ^^^^^^^^ cannot move out of captured outer variable in an `FnMut` closure
Run Code Online (Sandbox Code Playgroud)
在这里,我们试图移动f到闭包,这绝对是不可能的(除非m是1,但编译器无法知道).
既然f是a Fn(usize, usize) -> T,我们也可以明确地传递&对它的引用,&引用是Copy:
fn make<T, F>(n: usize, m: usize, f: F) -> Vec<T>
where
F: Fn(usize, usize) -> T,
{
let f_ref = &f;
(0..m)
.flat_map(|y| (0..n).map(move |x| f_ref(x, y)))
.collect()
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,闭包是按价值来看待它的环境,而这个环境是由y和f_ref它们组成的Copy,一切都很好.
| 归档时间: |
|
| 查看次数: |
1006 次 |
| 最近记录: |