flat_map 借来的时候丢在这里

flat_map dropped here while still borrowed

我正在尝试编写一个包含字符串索引和字符串中每个字符的向量。

在下面的例子中,0 J, 0 a, 0 n ... 1 J, 1i, ...

fn main() {
    let names = vec!["Jane", "Jill", "Jack", "Johne"];
    let name3 = names.iter().enumerate().flat_map(|(i, name)| {
        let letters = name.chars();
        let mut is = Vec::new();
        for _k in 0..name.len() {
            is.push(i);
        }
        is.iter().zip(letters).collect::<Vec<_>>()
    });
    for i in name3 {
        println!("{:?}", i);
    }
}

这给了我错误

error[E0597]: `is` does not live long enough
  --> src/main.rs:9:9
   |
9  |         is.iter().zip(letters).collect::<Vec<_>>()
   |         ^^ borrowed value does not live long enough
10 |     });
   |     - `is` dropped here while still borrowed
...
14 | }
   | - borrowed value needs to live until here

我不明白这是怎么回事。我已经收集了 is 值。

奇怪的是,如果我翻转 lettersis,它就起作用了。

letters.zip(is)

调用 is.iter() returns 引用 is 中的值。您的最终迭代器类型正在尝试 return 这些引用,除了保存值的 Vec 已经被释放。

最简单的解决方法是切换到 into_iter,它拥有 Vec 及其所有值的所有权。更有效的解决方法是完全避免创建 Vec

fn main() {
    let names = vec!["Jane", "Jill", "Jack", "Johne"];

    let name3 = names
        .iter()
        .enumerate()
        .flat_map(|(i, name)| name.chars().map(move |c| (i, c)));

    for i in name3 {
        println!("{:?}", i);
    }
}

if I flip letters and is, it works.

是的,zip takes values that implement IntoIterator。通过翻转参数,您最终会在 Vec 上隐式调用 into_iter。如果你这样做,你会得到同样的不良行为 letters.zip(&is).