20

この記事は最終更新日から3年以上が経過しています。

投稿日

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

こんばんは。 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>;
}

新規登録して、もっと便利にQiitaを使ってみよう

  1. あなたにマッチした記事をお届けします
  2. 便利な情報をあとで効率的に読み返せます
ログインすると使える機能について
wada314
@wada314
Ctrlキーを薬指で押しているので小指の痛さとは無縁なのですが、薬指が痛いです。

コメント

Conversions [Rust issue #7087]
ちょうどここで紹介されている規則ですね。
他にも as_ や to_ などの後ろに付く str とか string とか bytes とかは何やねんというルールもちゃんと紹介されている (Naming conventions) ので、 style guidelines は一度読んでおくと幸せになれるかと思います。

4
(編集済み)

和訳してくれている方もいますね

こういう発見性が低い知識を紹介してくれる記事はありがたいです

1
あなたもコメントしてみませんか :)
新規登録
すでにアカウントを持っている方はログイン
記事投稿キャンペーン開催中
RECOROKUを使ったナレッジ管理や情報共有のユースケースを投稿しよう!
~
新しくなったSkyWayを使ってみよう!
~
20