我可以通过这种方式将 Vec<String> 转换为 Vec<&str> :
Vec<String>
Vec<&str>
let mut items = Vec::<&str>::new(); for item in &another_items { items.push(item); }
我想有更好的选择?
这是另一种选择:
use std::iter::FromIterator; let v = Vec::from_iter(v.iter().map(String::as_str));
请注意,自Rust 1.7以来String::as_str是稳定的 .
another_items.iter().map(|item| item.deref()).collect::<Vec<&str>>()
要使用 deref() ,您必须使用 use std::ops::Deref 添加
deref()
use std::ops::Deref
这个使用 collect :
collect
let strs: Vec<&str> = another_items.iter().map(|s| s as &str).collect();
其他答案很简单 . 我只是想指出,如果你试图将 Vec<String> 转换为 Vec<&str> 只将其传递给以 Vec<&str> 为参数的函数,请考虑将函数签名修改为:
fn my_func<T: AsRef<str>>(list: &[T]) { ... }
代替:
fn my_func(list: &Vec<&str>) { ... }
正如这个问题所指出的那样:Function taking both owned and non-owned string collections . 通过这种方式,两个向量都可以简单地工作而无需转换 .
有很多方法可以做到这一点,有些方法有缺点,有些方法对某些人来说更具可读性 .
这将 s (其类型为 &String )取消引用到 String "right hand side reference",然后通过 Deref 特征将其解除引用至 str "right hand side reference"然后转回 &str . 这是编译器中常见的东西,因此我认为它是惯用的 .
s
&String
String
Deref
str
&str
let v2: Vec<&str> = v.iter().map(|s| &**s).collect();
这里 Deref 特征的 deref 函数被传递给 map 函数 . 它非常整洁,但需要 use 特性或提供完整的路径 .
deref
map
use
let v3: Vec<&str> = v.iter().map(std::ops::Deref::deref).collect();
这是不推荐的,你不应该这样做,因为它可以在将来使用 |s| s: &str (强制语法)完成 .
|s| s: &str
let v4: Vec<&str> = v.iter().map(|s| s as &str).collect();
这需要 RangeFull 的 RangeFull 切片(只是整个 String 的一个切片)并接受它的引用 . 在我看来这很难看 .
RangeFull
let v5: Vec<&str> = v.iter().map(|s| &s[..]).collect();
这是使用强制将 &String 转换为 &str . 也可以在将来用 s: &str 表达式替换 .
s: &str
let v6: Vec<&str> = v.iter().map(|s| { let s: &str = s; s }).collect();
以下(感谢@ huon-dbaupp)使用 AsRef trait,它仅用于从拥有的类型映射到它们各自的借用类型 . 有两种方法可以使用它,而且,任何一种版本的漂亮都是完全主观的 .
AsRef
let v7: Vec<&str> = v.iter().map(|s| s.as_ref()).collect();
和
let v8: Vec<&str> = v.iter().map(AsRef::as_ref).collect();
我的底线是使用 v8 解决方案,因为它最明确地表达了你想要的东西 .
v8
5 回答
这是另一种选择:
请注意,自Rust 1.7以来String::as_str是稳定的 .
要使用
deref()
,您必须使用use std::ops::Deref
添加这个使用
collect
:其他答案很简单 . 我只是想指出,如果你试图将
Vec<String>
转换为Vec<&str>
只将其传递给以Vec<&str>
为参数的函数,请考虑将函数签名修改为:代替:
正如这个问题所指出的那样:Function taking both owned and non-owned string collections . 通过这种方式,两个向量都可以简单地工作而无需转换 .
有很多方法可以做到这一点,有些方法有缺点,有些方法对某些人来说更具可读性 .
这将
s
(其类型为&String
)取消引用到String
"right hand side reference",然后通过Deref
特征将其解除引用至str
"right hand side reference"然后转回&str
. 这是编译器中常见的东西,因此我认为它是惯用的 .这里
Deref
特征的deref
函数被传递给map
函数 . 它非常整洁,但需要use
特性或提供完整的路径 .这是不推荐的,你不应该这样做,因为它可以在将来使用
|s| s: &str
(强制语法)完成 .这需要
RangeFull
的RangeFull
切片(只是整个String
的一个切片)并接受它的引用 . 在我看来这很难看 .这是使用强制将
&String
转换为&str
. 也可以在将来用s: &str
表达式替换 .以下(感谢@ huon-dbaupp)使用
AsRef
trait,它仅用于从拥有的类型映射到它们各自的借用类型 . 有两种方法可以使用它,而且,任何一种版本的漂亮都是完全主观的 .和
我的底线是使用
v8
解决方案,因为它最明确地表达了你想要的东西 .