我有一种我无法向自己解释的奇怪行为。如果想通过迭代两个
Vec<String>
来创建新字符串,但不知何故通过索引访问不起作用,因为我借了东西。我的困惑来自于这样一个事实:索引不应该被复制,因为它是一个原始时间。
如果我直接迭代 Vec<String>
,则该示例
does会起作用。编译器错误建议在第二个
move
中使用 map
并不能解决问题。
这是我的例子:
fn f() -> Vec<String> {
let num_outer = 2;
let num_inner = 3;
let outer_names = vec!["1", "2"];
let inner_names = vec!["x", "y", "z"];
(0..num_outer)
.into_iter()
.map(|outer_index| {
(0..num_inner).into_iter().map(|inner_index| {
format!(
"tuple ({},{})",
outer_names[outer_index], inner_names[inner_index],
)
})
})
.flatten()
.collect::<Vec<String>>()
}
fn main() {
let x = f();
println!("{:?}", &x);
}
这是因为您需要闭包通过
move
(或通过 Copy
,因为它们是 Copy
类型)捕获索引,而且还通过引用捕获 Vec
。 Rust 只允许您在语法上选择一种类型的捕获(如果您创建 move
闭包,则通过 move
进行捕获,否则它将通过引用捕获所有内容)。
但是,手动操作很容易。您只需使用
move
闭包和在闭包之前创建的“移入”引用即可。在你的情况下,这有效:
fn f() -> Vec<String> {
let num_outer = 2;
let num_inner = 3;
let outer_names = vec!["1", "2"];
let inner_names = vec!["x", "y", "z"];
let outer_names_ref = &outer_names;
let inner_names_ref = &inner_names;
(0..num_outer)
.flat_map(|outer_index| {
(0..num_inner).map(move |inner_index| {
format!(
"tuple ({},{})",
outer_names_ref[outer_index], inner_names_ref[inner_index],
)
})
})
.collect::<Vec<String>>()
}
fn main() {
let x = f();
println!("{:?}", &x);
}
注意,我还删除了不必要的
into_iter
,因为范围文字已经是迭代器。我也切换到了flat_map
,因为clippy建议了它(使用clippy!这太棒了:))