LoginSignup
30
21

More than 5 years have passed since last update.

as_str()とかto_string()とかinto_vec()とか紛らわしい!

Posted at

こんばんは。 Rust、よく型を明示的に変換しますよね。
&strからStringとか、Vec<T>から&[T]とかが代表ですが、他にも標準ライブラリだけでもいろいろな変換メソッドが用意されています。
ところでこれらの変換メソッド、名前がas_str()とかto_string()とかinto_vec()とかだったりして前置詞が紛らわしいんじゃ! と思ったことはありませんか? 実はこれにはちゃんと法則性があるということに、Rust歴7年の私はたった今気づきました。

as_***

&selfをとって、同じlifetimeの参照を返すメソッドです。 要するに、ただ参照をキャストしているだけか、メンバへの参照を返しているだけです。 標準ライブラリから適当に例を挙げると、

impl String {
  fn as_str(&self) -> &str;
}
impl<T> Vec<T> {
  fn as_slice(&self) -> &[T];
}
impl<T> Option<T> {
  fn as_ref(&self) -> Option<&T>;
}

などです。 Option<T>のはちょっと特殊ですが、まぁ気持ちはわかるのでいいです。

to_***

&selfをとって、新しくオブジェクトを作って返すメソッドです。 as_***と違い、多くの場合&selfと戻り値の間にlifetimeの関係がないのが特徴です。 標準ライブラリでは例えば、

impl i32 {
  fn to_string(&self) -> String
}
impl<T> [T] {
  fn to_vec(&self) -> Vec<T> where T: Clone;
}
impl<'a, T> Cow<'a, T> {
  fn to_mut(&mut self) -> &mut <T as ToOwned>::Owned;
}

などがあります。 最後のCowの例は特殊で、新しくオブジェクトを作るかもしれないし作らないかもしれないメソッドです。 これはastoの境界にいる感じがしますね。

into_***

selfを食べて(&selfではない点に注意)、何かを返すメソッドです。 selfは食べられるので以後使えなくなるのが特徴です。

impl<T> [T] {
  // Box<[T]>の領域を使い回す変換メソッド
  fn into_vec(self: Box<[T]>) -> Vec<T>;
}
impl String {
  // やはりStringの領域を使い回すメソッド
  fn into_bytes(self) -> Vec<u8>;
}
30
21
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
21