変換できますVec<String>
からVec<&str>
こちらです:
let mut items = Vec::<&str>::new();
for item in &another_items {
items.Push(item);
}
より良い代替案はありますか?
それを行うにはかなり多くの方法があり、いくつかは不利な点があり、他の人は単に一部の人々にとってより読みやすいです。
これは、s
(右側の参照)にString
(タイプ&String
)を逆参照し、Deref
特性を介してstr
"右側の参照"に逆参照され、&str
に戻ります。これはコンパイラーで非常によく見られるものであり、私はそれを慣用的と考えています。
let v2: Vec<&str> = v.iter().map(|s| &**s).collect();
ここでは、deref
トレイトのDeref
関数がmap
関数に渡されます。かなりすっきりしていますが、特性をuse
ingするか、完全なパスを指定する必要があります。
let v3: Vec<&str> = v.iter().map(std::ops::Deref::deref).collect();
これは強制型構文を使用します。
let v4: Vec<&str> = v.iter().map(|s| s as &str).collect();
これは、RangeFull
のString
スライス(String
全体へのスライス)を受け取り、それへの参照を受け取ります。私の意見では醜いです。
let v5: Vec<&str> = v.iter().map(|s| &s[..]).collect();
これは、強制を使用して&String
を&str
に変換します。将来はs: &str
式で置き換えることもできます。
let v6: Vec<&str> = v.iter().map(|s| { let s: &str = s; s }).collect();
以下(@ huon-dbauppに感謝)では、AsRef
トレイトを使用しています。それを使用するには2つの方法があり、どちらのバージョンのかわいさも完全に主観的です。
let v7: Vec<&str> = v.iter().map(|s| s.as_ref()).collect();
そして
let v8: Vec<&str> = v.iter().map(AsRef::as_ref).collect();
私の一番下の行は、v8
ソリューションを使用することです。それは、あなたが望むものを最も明確に表現するからです。
他の答えは単に機能します。 Vec<String>
をVec<&str>
に変換してVec<&str>
を引数として関数に渡す場合は、関数のシグネチャを次のように変更することを検討してください。
fn my_func<T: AsRef<str>>(list: &[T]) { ... }
の代わりに:
fn my_func(list: &Vec<&str>) { ... }
この質問で指摘されているように、 所有されている文字列コレクションと所有されていない文字列コレクションの両方をとる関数 。このようにして、両方のベクトルは変換を必要とせずに機能します。
_another_items.iter().map(|item| item.deref()).collect::<Vec<&str>>()
_
deref()
を使用するには、_use std::ops::Deref
_を使用して追加する必要があります
これはcollect
を使用します:
let strs: Vec<&str> = another_items.iter().map(|s| s as &str).collect();
ここに別のオプションがあります:
use std::iter::FromIterator;
let v = Vec::from_iter(v.iter().map(String::as_str));
ご了承ください - String::as_str
は、Rust 1.7。