rust - 使用 flat_map 将 Vec<u8> 转换为 Vec<char>

标签 rust borrow-checker

我遇到了与 Borrow-check error with variable not living long enough in nested lambda 类似的情况但无法弄清楚我的情况有何不同:

let mut vec = vec![vec![0u8, 1u8], vec![2u8, 3u8], vec![4u8, 5u8]];
vec.iter().map(|row| {
    row.iter()
        .map(|d| format!("{:04b}", d))
        .flat_map(|s| s.chars())
        .collect::<Vec<_>>()
});

这给出了错误:

error[E0597]: `s` does not live long enough
 --> src/main.rs:6:35
  |
6 |             .flat_map(|s| s.chars())
  |                           -       ^ `s` dropped here while still borrowed
  |                           |
  |                           borrow occurs here
7 |             .collect::<Vec<_>>()
  |                                - borrowed value needs to live until here

我通过创建一个新的 Vec 并附加来解决这个问题,但我不清楚为什么第一种方法不起作用。

let mut tmp = vec![];
vec.iter()
    .map(|d| format!("{:04b}", d))
    .for_each(|s| {tmp.append(&mut s.chars().collect::<Vec<_>>());});

最佳答案

你首先映射闭包|d| format!("{:04b}", d) 在你的迭代器上,产生 Strings,它拥有自己的数据,所以这完美地找到了。下一步中的 flat_map() 在每个 String 上调用 .chars()。这隐式地将 String 取消引用为 &str,并创建引用此借用的 Chars 迭代器。但现在我们遇到了一个问题——没有人拥有我们借用的 String

一种解决方法是存储 String 的临时向量:

let mut vec = vec![vec![0u8, 1u8], vec![2u8, 3u8], vec![4u8, 5u8]];
vec.iter().map(|row| {
    let strings: Vec<_> = row
        .iter()
        .map(|d| format!("{:04b}", d))
        .collect();
    strings
        .iter()
        .flat_map(|s| s.chars())
        .collect::<Vec<_>>()
});

现在我们有了中介 String 的所有者,一切又恢复正常了。

关于rust - 使用 flat_map 将 Vec<u8> 转换为 Vec<char>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47822349/

相关文章:

rust - 拥有指向特征的指针

rust - 如何在循环内交换 Vec 的两个索引的内容?

rust - 如何在 HashMap 字段中保存对处理程序的引用

rust - 即使 NLL 打开,循环中的双可变借用错误也会发生

rust - 不能借用为不可变的,因为它在函数参数中也被借用为可变的

rust - 如果我在代码的各个位置使用了非可变变量,为什么会出现借来的错误?

types - isize 和 usize 的可用性如何,为什么它们有利于索引?

testing - 当 HTTP 服务器在旧服务器关闭后启动时,测试会发生 panic

rust - 允许使用用户定义类型创建特征对象?

rust - 返回对外部引用的过滤向量的引用时如何安抚借用检查器