首页 > 解决方案 > 转 Vec进入 Vec<(&str, u64)> 获取 tui::BarChart 数据

问题描述

我怎样才能把 aVec<u64>变成 a Vec<(&str, u64)>,使前者的索引嵌入到str后者的一部分中?

例如,[4, 9, 3]应该变成[("0", 4), ("1", 9), ("2", 3)].

我想这样做的原因是因为我想使用来自 TUI 的条形图绘制我的向量的条形图,这需要这样的类型。

我尝试了一些明显的事情,例如循环和推送:

fn main() {
    let my_vec: Vec<u64> = vec![4, 9, 3];
    let mut result: Vec<(&str, u64)> = Vec::new();
    for (k, v) in my_vec.iter().enumerate() {
        result.push((&k.to_string(), *v));
    }

    assert_eq!(result, [("0", 4), ("1", 9), ("2", 3)]);
}
error[E0716]: temporary value dropped while borrowed
 --> src/main.rs:5:23
  |
5 |         result.push((&k.to_string(), *v));
  |                       ^^^^^^^^^^^^^      - temporary value is freed at the end of this statement
  |                       |
  |                       creates a temporary which is freed while still in use
...
8 |     assert_eq!(result, [("0", 4), ("1", 9), ("2", 3)]);
  |     --------------------------------------------------- borrow later used here
  |
  = note: consider using a `let` binding to create a longer lived value

或使用map

fn main() {
    let my_vec: Vec<u64> = vec![4, 9, 3];
    let result: Vec<(&str, u64)> = my_vec
        .into_iter()
        .enumerate()
        .map(|(k, v)| (&k.to_string(), v))
        .collect();

    assert_eq!(result, [("0", 4), ("1", 9), ("2", 3)]);
}
error[E0277]: a value of type `std::vec::Vec<(&str, u64)>` cannot be built from an iterator over elements of type `(&std::string::String, u64)`
 --> src/main.rs:7:10
  |
7 |         .collect();
  |          ^^^^^^^ value of type `std::vec::Vec<(&str, u64)>` cannot be built from `std::iter::Iterator<Item=(&std::string::String, u64)>`
  |
  = help: the trait `std::iter::FromIterator<(&std::string::String, u64)>` is not implemented for `std::vec::Vec<(&str, u64)>`

但无论我做什么,我似乎都无法解决终身问题,因为k.to_string()活得不够长。

当然,如果有更好的方法来绘制带有索引作为标签的向量,我愿意接受建议。

标签: rust

解决方案


您不能直接这样做,&str借用字符串,因此在您借用字符串时字符串必须保持活动状态,一般的答案是创建您的字符串,存储它们并借用它们,例如:

fn main() {
    let my_vec: Vec<u64> = vec![4, 9, 3];

    let my_owned : Vec<(String, u64)> = my_vec
        .into_iter()
        .enumerate()
        .map(|(k, v)| (k.to_string(), v))
        .collect();

    let result: Vec<(&str, u64)> = my_owned
        .iter()
        .map(|(k, v)| (k.as_str(), *v))
        .collect();

    assert_eq!(result, [("0", 4), ("1", 9), ("2", 3)]);
}

虽然这将适用于您的具体情况,但data()很奇怪。如果不深入挖掘,很难判断是否有问题。在您链接的示例中,它们str是静态的,可能只是(或主要)打算像示例一样使用,因此您不希望将它与动态索引一起使用。


推荐阅读