&str
を String
に変換する主なやりかたには以下の4つがある。どれを選ぶかは好みで決めていい。ただし "str".into()
は使いどころがやや異なる。
"str".to_string()
std::string::ToString
トレイトに従って str
が間接的に1実装するメソッド。他の言語にも同名もしくは似た名前のメソッドがあるため、多くの人がまず使うのはこれであろうと思われる。
Rust 1.9 以降では、このメソッドは特殊化されており String::from()
に等しい:
#[stable(feature = "str_to_string_specialization", since = "1.9.0")]
impl ToString for str {
#[inline]
fn to_string(&self) -> String {
String::from(self)
}
}
Rust 1.9 未満では、このメソッドは以下のように write_fmt()
を呼び出しており、他の3つの方法に比べてわずかながらオーバーヘッドが大きい:
impl<T: fmt::Display + ?Sized> ToString for T {
#[inline]
fn to_string(&self) -> String {
use core::fmt::Write;
let mut buf = String::new();
let _ = buf.write_fmt(format_args!("{}", self));
buf.shrink_to_fit();
buf
}
}
"str".to_owned()
std::borrowed::ToOwned
トレイト2に従って str
が実装するメソッド。 to_string()
よりも1文字短いのが利点。
String::from("str")
std::convert::From<T>
トレイトに従って String
が実装する関数。4つの中で最長の名前だが、その自明さを好む人もいる。
"str".into()
std::convert::Into<T>
トレイトに従って &str
が間接的に3実装するメソッド。 into()
の返り値の型が String
と推論可能でなければエラーになるため、使いどころが限られる:
let s = "str".into(); // s の型が推論できないのでコンパイルエラーになる
println!("{}", s);
into()
が活躍するのは String
と &str
のどちらでも引数に取れる関数を書くときだ:
fn some_string<S: Into<String>>(s: S) -> Option<String> {
Some(s.into())
}
let s1 = some_string("str");
let s2 = some_string("str".to_string());
assert_eq!(s1, s2);