提问人:exocortex 提问时间:10/23/2023 更新时间:10/26/2023 访问量:76
在嵌套迭代器中,按索引访问向量不起作用
In nested iterators accessing vector by index does not work
问:
我有一个奇怪的行为,我无法向自己解释。如果想通过遍历两个 's 来创建新的字符串,但不知何故通过索引访问不起作用,因为我借用了东西。我的困惑来自这样一个事实,即索引不应该被复制,因为它是一个原始时间。Vec<String>
如果我直接遍历 's,该示例确实有效。编译器错误建议在第二个中使用并不能解决问题。Vec<String>
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);
}
答:
2赞
JMAA
10/23/2023
#1
这是因为您需要闭包来捕获索引 by (或 by ,因为它们是类型),但也需要通过引用捕获 s。Rust 只允许你在语法上选择一种类型的捕获(如果你做了一个闭包,它就会通过引用来捕获所有内容)。move
Copy
Copy
Vec
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);
}
注意:我还删除了不必要的 s,因为范围文字已经是迭代器。我也改用了,因为 clippy 建议它(使用 clippy! 这很棒:))into_iter
flat_map
通常,如果您需要闭包的“混合捕获”(即,某些变量的移动捕获,其他变量的引用捕获),这是执行此操作的方法。您使用闭包,但您显式创建了需要移入的引用,以便“通过引用”捕获内容。move
评论
0赞
cafce25
10/23/2023
默认设置不是通过引用捕获所有内容,而是通过引用的第一个,独占引用,与语义一起使用的移动。J.F. 确实移动了 x
let x = String::new(); let f = || x;
0赞
Kaplan
10/26/2023
#2
当然,同样的东西也可以用 2 个循环写得更短:
fn f() -> Vec<String> {
let num_outer = 2;
let num_inner = 3;
let outer_names = ["1", "2"];
let inner_names = ["x", "y", "z"];
let mut rslt = vec![];
for outer in outer_names.iter().take(num_outer) {
for inner in inner_names.iter().take(num_inner) {
rslt.push(format!(
"tuple ({outer}, {inner})"
));
}
}
rslt
}
评论
0赞
exocortex
10/27/2023
是的,这也行得通。我用了一段时间的那个版本。我主要想了解在数组中使用诱导时出现此错误的原因。
0赞
Kaplan
10/27/2023
明白了。然而,在生产代码中,我更喜欢这种 2 循环解决方案,因为它的清晰度和更高的速度。
0赞
exocortex
10/28/2023
是的,当然!这只是我写的东西中发生的一个问题,它必须是这样的。我做了这个简单的例子,只是为了用更简单的方式说明这个问题。
评论