每个Steve Klabnik's writeup in the pre-Rust 1.0 documentation on the difference between String
and &str
,在Rust中你应该使用&str
,除非你真的需要拥有String
的所有权。同样,建议使用对切片(&[]
)而不是Vec
的引用,除非您确实需要Vec
的所有权。
我有一个Vec<String>
,我想写一个使用这个字符串序列的函数,它不需要Vec
或String
个实例的所有权,如果该函数需要&[&str]
?如果是,那么将Vec<String>
引用到&[&str]
的最佳方式是什么?或者,这种强制是否过度杀伤?
答案 0 :(得分:23)
您可以使用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);
}
答案 1 :(得分:6)
如果没有内存分配 1 ,这实际上是不可能的。
问题是,从String
到&str
不仅仅是以不同的方式查看这些位; String
和&str
具有不同的内存布局,因此从一个到另一个需要创建一个新对象。这同样适用于Vec
和&[]
因此,虽然您可以从Vec<T>
转到&[T]
,从Vec<String>
转到&[String]
,但您无法直接从Vec<String>
转到{{} 1}}:
&[&str]
&[String]
的新Vec<&str>
,并将 转换为Vec
1 所需的转换是不可能的,但是使用泛型和&[&str]
绑定,如@aSpex的答案所示,你会得到更多详细的函数声明,具有您所要求的灵活性。