在 Rust 中将 Vec<String> 转换为 &str 的一部分?

Convert Vec<String> into a slice of &str in Rust?

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

的所有权

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

如果没有内存分配或每个元素调用,这实际上是不可能的1.

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

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

  • 要么接受 &[String]
  • 分配一个新的 Vec<&str> 引用第一个 Vec,并将 that 转换为 &[&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<str> 绑定,如 @aSpex 的答案所示,您会得到稍微冗长的函数声明具有您要求的灵活性,但您必须在所有元素中调用 .as_ref()

您可以使用 AsRef trait:

创建一个同时接受 &[String]&[&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);
}