【问题标题】:flat_map dropped here while still borrowedflat_map 在还借来的时候掉到了这里
【发布时间】:2018-03-27 14:12:43
【问题描述】:

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

在下面的例子中,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)

【问题讨论】:

    标签: dictionary rust flat


    【解决方案1】:

    调用is.iter() 会返回对is 内部值的引用。您的最终迭代器类型正在尝试返回这些引用,但持有这些值的 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);
        }
    }
    

    如果我翻转lettersis,它会起作用。

    是的,zip 采用实现 IntoIterator 的值。通过翻转参数,您最终会在Vec 上隐式调用into_iter。如果您执行letters.zip(&amp;is),您会得到同样的不良行为。

    【讨论】:

    • 谢谢。我不知道 into_iter。这篇文章对此很有帮助。 hermanradtke.com/2015/06/22/…
    • 您使用 move c 的解决方案也非常优雅。谢谢。
    猜你喜欢
    • 2018-12-13
    • 2016-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-19
    • 2019-05-12
    • 2010-10-21
    • 1970-01-01
    相关资源
    最近更新 更多