将 Vec<String> 转换为 Rust 中的 &str 切片?

Posted

技术标签:

【中文标题】将 Vec<String> 转换为 Rust 中的 &str 切片?【英文标题】:Convert Vec<String> into a slice of &str in Rust? 【发布时间】: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] 的最佳方法是什么?或者,这种强制是不是矫枉过正?

【问题讨论】:

【参考方案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))。

以上是关于将 Vec<String> 转换为 Rust 中的 &str 切片?的主要内容,如果未能解决你的问题,请参考以下文章

为什么使用Vec :: contains时&str不会强制转换为&String?

将 vec3b 转换为 mat

如何将 Rust `Vec<T>` 暴露给 FFI?

std::vector<cv::Vec3b> 到 cv::Mat

如何在java中将String转换为DOM Document对象?

是否有一个转换Vec的好方法 到阵列? [重复]