在 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
的所有权。同样,建议使用对切片 (&[]
) 的引用而不是 Vec
s,除非你真的需要对 Vec
.
的所有权
我有一个 Vec<String>
,我想编写一个使用这个字符串序列的函数,它不需要 Vec
或 String
实例的所有权,如果函数取 &[&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);
}
根据 Steve Klabnik's writeup in the pre-Rust 1.0 documentation on the difference between String
and &str
,在 Rust 中你应该使用 &str
除非你真的需要拥有 String
的所有权。同样,建议使用对切片 (&[]
) 的引用而不是 Vec
s,除非你真的需要对 Vec
.
我有一个 Vec<String>
,我想编写一个使用这个字符串序列的函数,它不需要 Vec
或 String
实例的所有权,如果函数取 &[&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);
}