在嵌套迭代器中通过索引访问向量不起作用

问题描述 投票:0回答:1

我有一种我无法向自己解释的奇怪行为。如果想通过迭代两个

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);
}
rust iterator closures
1个回答
0
投票

这是因为您需要闭包通过

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!这太棒了:))

© www.soinside.com 2019 - 2024. All rights reserved.