首页 文章

将Vec <String>转换为Vec <&str>

提问于
浏览
23

我可以通过这种方式将 Vec<String> 转换为 Vec<&str>

let mut items = Vec::<&str>::new();
for item in &another_items {
    items.push(item);
}

我想有更好的选择?

5 回答

  • 6

    这是另一种选择:

    use std::iter::FromIterator;
    
    let v = Vec::from_iter(v.iter().map(String::as_str));
    

    请注意,自Rust 1.7以来String::as_str是稳定的 .

  • 24
    another_items.iter().map(|item| item.deref()).collect::<Vec<&str>>()
    

    要使用 deref() ,您必须使用 use std::ops::Deref 添加

  • 1

    这个使用 collect

    let strs: Vec<&str> = another_items.iter().map(|s| s as &str).collect();
    
  • 0

    其他答案很简单 . 我只是想指出,如果你试图将 Vec<String> 转换为 Vec<&str> 只将其传递给以 Vec<&str> 为参数的函数,请考虑将函数签名修改为:

    fn my_func<T: AsRef<str>>(list: &[T]) { ... }
    

    代替:

    fn my_func(list: &Vec<&str>) { ... }
    

    正如这个问题所指出的那样:Function taking both owned and non-owned string collections . 通过这种方式,两个向量都可以简单地工作而无需转换 .

  • 2

    有很多方法可以做到这一点,有些方法有缺点,有些方法对某些人来说更具可读性 .

    这将 s (其类型为 &String )取消引用到 String "right hand side reference",然后通过 Deref 特征将其解除引用至 str "right hand side reference"然后转回 &str . 这是编译器中常见的东西,因此我认为它是惯用的 .

    let v2: Vec<&str> = v.iter().map(|s| &**s).collect();
    

    这里 Deref 特征的 deref 函数被传递给 map 函数 . 它非常整洁,但需要 use 特性或提供完整的路径 .

    let v3: Vec<&str> = v.iter().map(std::ops::Deref::deref).collect();
    

    这是不推荐的,你不应该这样做,因为它可以在将来使用 |s| s: &str (强制语法)完成 .

    let v4: Vec<&str> = v.iter().map(|s| s as &str).collect();
    

    这需要 RangeFullRangeFull 切片(只是整个 String 的一个切片)并接受它的引用 . 在我看来这很难看 .

    let v5: Vec<&str> = v.iter().map(|s| &s[..]).collect();
    

    这是使用强制将 &String 转换为 &str . 也可以在将来用 s: &str 表达式替换 .

    let v6: Vec<&str> = v.iter().map(|s| { let s: &str = s; s }).collect();
    

    以下(感谢@ huon-dbaupp)使用 AsRef trait,它仅用于从拥有的类型映射到它们各自的借用类型 . 有两种方法可以使用它,而且,任何一种版本的漂亮都是完全主观的 .

    let v7: Vec<&str> = v.iter().map(|s| s.as_ref()).collect();
    

    let v8: Vec<&str> = v.iter().map(AsRef::as_ref).collect();
    

    我的底线是使用 v8 解决方案,因为它最明确地表达了你想要的东西 .

相关问题