【问题标题】:Convert Vec<String> into a slice of &str in Rust?将 Vec<String> 转换为 Rust 中的 &str 切片?
【发布时间】:2017-05-01 23:17:49
【问题描述】:

根据Steve Klabnik's writeup in the pre-Rust 1.0 documentation on the difference between String and &amp;str,在Rust 中你应该使用&amp;str,除非你真的需要拥有String 的所有权。同样,除非您确实需要对 Vec 的所有权,否则建议使用对切片 (&amp;[]) 的引用而不是 Vecs。

我有一个Vec&lt;String&gt;,我想编写一个使用此字符串序列的函数,它不需要拥有VecString 实例的所有权,该函数是否应该采用&amp;[&amp;str]?如果是这样,将Vec&lt;String&gt; 引用到&amp;[&amp;str] 的最佳方法是什么?或者,这种强制是不是矫枉过正?

【问题讨论】:

    标签: string vector reference rust ownership


    【解决方案1】:

    您可以使用AsRef trait 创建一个同时接受&amp;[String]&amp;[&amp;str] 的函数:

    fn test<T: AsRef<str>>(inp: &[T]) {
        for x in inp { print!("{} ", x.as_ref()) }
        println!("");
    }
    
    fn main() {
        let vref = vec!["Hello", "world!"];
        let vown = vec!["May the Force".to_owned(), "be with you.".to_owned()];
        test(&vref);
        test(&vown);
    }
    

    【讨论】:

    • 我认为这是 OP 正在寻找的答案,因为它允许在没有不必要分配的情况下使用切片。这种方法在接受 AsRef&lt;Path&gt; 的切片时更加有用 - 您希望函数接受所有 &amp;[&amp;str]&amp;[String]&amp;[Path]&amp;[PathBuf],而不分配新内存。
    • 一件可悲的事情是,如果您尝试使用Option&lt;&amp;[T]&gt;,您不能只通过None 而不指定具体类型
    【解决方案2】:

    如果没有内存分配,这实际上是不可能的1

    String&amp;str 不仅仅是从不同的角度看待比特; String&amp;str 具有不同的内存布局,因此从一个到另一个需要创建一个新对象。这同样适用于Vec&amp;[]

    因此,虽然您可以从Vec&lt;T&gt; 转到&amp;[T],从而从Vec&lt;String&gt; 转到&amp;[String],但您不能直接从Vec&lt;String&gt; 转到&amp;[&amp;str]。您的选择是:

    • 要么接受&amp;[String]
    • 分配一个新的Vec&lt;&amp;str&gt;引用第一个Vec,并将那个转换成&amp;[&amp;str]

    以分配为例:

    fn usage(_: &[&str]) {}
    
    fn main() {
        let owned = vec![String::new()];
    
        let half_owned: Vec<_> = owned.iter().map(String::as_str).collect();
    
        usage(&half_owned);
    }
    

    1所需的转换是不可能的,但是使用泛型和AsRef&lt;str&gt; 绑定,如@aSpex 的答案所示,您会得到一个稍微冗长的函数声明,并且具有您的灵活性要求。

    【讨论】:

    • 谢谢,马修。对于我现在的情况,我想我会选择&amp;[String],因为我认为分配一个新的Vec&lt;&amp;str&gt; 会产生额外的工作。
    • @DonRowe:它会产生额外的分配(O(1) 但可能很昂贵)+ 转换(O(n))。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-30
    • 1970-01-01
    • 1970-01-01
    • 2021-03-16
    • 1970-01-01
    相关资源
    最近更新 更多