flat_map虽然仍然借用,但仍然放在这里

时间:2018-03-27 14:12:43

标签: dictionary rust flat

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

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

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)

1 个答案:

答案 0 :(得分:6)

调用is.iter()会返回对is内的值的引用。您的最终迭代器类型正在尝试返回这些引用,但保存值的Vec已被释放。

最简单的解决方法是切换到into_iterVec拥有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); } }

letters
  

如果我翻转isinto_iter,它就有效。

是的,zip采用实施IntoIterator的值。通过翻转参数,您最终会在Vec上隐式调用letters.zip(&is)。如果你做chef-client -o 'recipe[cookbook]' -j attributes-file.json ,你会得到同样不受欢迎的行为。