我认为这两种方法是等价的,但有一个错误。原因何在?有没有更好的表达方式?
pub fn create_pair() -> () {
let vec_num = vec![1, 2, 3];
let vec_num2 = &vec_num;
let all = &vec_num
.iter()
.flat_map(move |a| vec_num2.iter().map(move |b| [a, b]))
.collect::<Vec<_>>();
println!("{:?}", all);
}[[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]pub fn create_pair() -> () {
let vec_num = vec![1, 2, 3];
let all = &vec_num
.iter()
.flat_map(move |a| &vec_num.iter().map(move |b| [a, b]))
.collect::<Vec<_>>();
println!("{:?}", all);
}error[E0277]: `&std::iter::Map<std::slice::Iter<'_, {integer}>, [closure@src/main.rs:5:48: 5:63 a:_]>` is not an iterator
--> src/main.rs:5:10
|
5 | .flat_map(move |a| &vec_num.iter().map(move |b| [a, b]))
| ^^^^^^^^ `&std::iter::Map<std::slice::Iter<'_, {integer}>, [closure@src/main.rs:5:48: 5:63 a:_]>` is not an iterator
|
= help: the trait `std::iter::Iterator` is not implemented for `&std::iter::Map<std::slice::Iter<'_, {integer}>, [closure@src/main.rs:5:48: 5:63 a:_]>`
= note: required because of the requirements on the impl of `std::iter::IntoIterator` for `&std::iter::Map<std::slice::Iter<'_, {integer}>, [closure@src/main.rs:5:48: 5:63 a:_]>`
error[E0599]: no method named `collect` found for struct `std::iter::FlatMap<std::slice::Iter<'_, {integer}>, &std::iter::Map<std::slice::Iter<'_, {integer}>, [closure@src/main.rs:5:48: 5:63 a:_]>, [closure@src/main.rs:5:19: 5:64 vec_num:_]>` in the current scope
--> src/main.rs:6:10
|
6 | .collect::<Vec<_>>();
| ^^^^^^^ method not found in `std::iter::FlatMap<std::slice::Iter<'_, {integer}>, &std::iter::Map<std::slice::Iter<'_, {integer}>, [closure@src/main.rs:5:48: 5:63 a:_]>, [closure@src/main.rs:5:19: 5:64 vec_num:_]>`
|
= note: the method `collect` exists but the following trait bounds were not satisfied:
`&std::iter::Map<std::slice::Iter<'_, {integer}>, [closure@src/main.rs:5:48: 5:63 a:_]>: std::iter::IntoIterator`
which is required by `std::iter::FlatMap<std::slice::Iter<'_, {integer}>, &std::iter::Map<std::slice::Iter<'_, {integer}>, [closure@src/main.rs:5:48: 5:63 a:_]>, [closure@src/main.rs:5:19: 5:64 vec_num:_]>: std::iter::Iterator`
`std::iter::FlatMap<std::slice::Iter<'_, {integer}>, &std::iter::Map<std::slice::Iter<'_, {integer}>, [closure@src/main.rs:5:48: 5:63 a:_]>, [closure@src/main.rs:5:19: 5:64 vec_num:_]>: std::iter::Iterator`
which is required by `&mut std::iter::FlatMap<std::slice::Iter<'_, {integer}>, &std::iter::Map<std::slice::Iter<'_, {integer}>, [closure@src/main.rs:5:48: 5:63 a:_]>, [closure@src/main.rs:5:19: 5:64 vec_num:_]>: std::iter::Iterator`发布于 2020-09-29 10:25:43
根据Rust reference,&操作符的优先级低于方法调用。所以这个闭包:
move |a| &vec_num.iter().map(move |b| [a, b])将首先尝试计算vec_num.iter().map(move |b| [a, b]),然后引用该结果并返回它。这根本不等同于你的第一个样本。
我有预感你的意思是:
move |a| (&vec_num).iter().map(move |b| [a, b])这也不起作用,但原因完全不同:
error: captured variable cannot escape `FnMut` closure body
--> src/main.rs:17:28
|
14 | let vec_num = vec![1, 2, 3];
| ------- variable defined here
...
17 | .flat_map(move |a| (&vec_num).iter().map(move |b| [a, b]))
| - ^^-------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| | | |
| | | variable captured here
| | returns a reference to a captured variable which escapes the closure body
| inferred to be a `FnMut` closure
|
= note: `FnMut` closures only have access to their captured variables while they are executing...
= note: ...therefore, they cannot allow references to captured variables to escape
error[E0505]: cannot move out of `vec_num` because it is borrowed
--> src/main.rs:17:19
|
15 | let all = &vec_num
| ------- borrow of `vec_num` occurs here
16 | .iter()
17 | .flat_map(move |a| (&vec_num).iter().map(move |b| [a, b]))
| -------- ^^^^^^^^ ------- move occurs due to use in closure
| | |
| | move out of `vec_num` occurs here
| borrow later used by call
error: aborting due to 2 previous errors您不能在将方法调用移到闭包中的同时,同时借用vec_num进行方法调用。而且,由于闭包现在拥有vec_num,所以不能返回最终包含对vec_num的引用的值,因为一旦从闭包返回,它就会被删除。
如果您移除了move,那么闭包将借用vec_num而不是消耗它。
同样,根据Rust参考:
闭包可以捕获变量:
它们优先通过引用捕获变量,只有在需要时才会降低。
您不需要&来指示应该通过引用捕获变量。这是可行的:
pub fn main() -> () {
let vec_num = vec![1, 2, 3];
let all = &vec_num
.iter()
.flat_map(|a| vec_num.iter().map(move |b| [a, b]))
.collect::<Vec<_>>();
println!("{:?}", all);
}https://stackoverflow.com/questions/64111547
复制相似问题