Option::as_ref などのメソッドについて。

基礎知識

構造はそのままに中の値のみを参照化する。

例えば、Option<T>as_refOption<&T> を戻す。

メソッド一覧

代表的なものをまとめておく。

as_ref … 参照化
Option<T>
fn as_ref(&self) -> Option<&T>
Result<T>
fn as_ref(&self) -> Result<&T>
Bound<T>
fn as_ref(&self) -> Bound<&T>

AsRef<T>::as_ref は用途が異なる (&T 型を返却)。

as_mut … 可変参照化
Option<T>
fn as_mut(&mut self) -> Option<&mut T>
Result<T>
fn as_mut(&mut self) -> Result<&mut T>
Bound<T>
fn as_mut(&mut self) -> Bound<&mut T>

Bound<T>::as_mut 時点でナイトリー。
AsMut<T>::as_mut は用途が異なる (&mut T 型を返却)。

as_derefDeref による参照化
Option<T>
fn as_deref(&self) -> Option<&<T as Deref>::Target>
Result<T>
fn as_deref(&self) -> Result<&<T as Deref>::Target>
as_deref_mutDerefMut による可変参照化
Option<T>
fn as_deref_mut(&mut self) -> Option<&mut <T as Deref>::Target>
Result<T>
fn as_deref_mut(&mut self) -> Result<&mut <T as Deref>::Target>

補足

as_derefas_deref_mut はそれぞれ as_refas_mut の参照からスマートポインタへの一般化である。中でも特によく見るパターンは as_deref による Option<String> から Option<&str> への変換である。

型全体への影響

as_ref がある型のメソッドは self&self よりもよく使う傾向にある。

例えば、Option 型の unwrapmap などのメソッドも self を使っている。

そして、opt.as_ref().unwrap() のようなコードがよく見られるようになる。

理由

as_ref を経由すると self&self のサイズ差が問題にならなくなる。

例えば、型 Option<T> とそれに as_ref を適用した型 Option<&T> を考える。

二つの型の self&self の実際の型はそれぞれ以下の通りとなる。

Option<T> Option<&T>
self Option<T> Option<&T>
&self &Option<T> &Option<&T>

ここで T のサイズが大きいと、Option<T> の列では self&self より大きくなる。一方、Option<&T> の列では両者の差は殆どない。そのため、as_ref がないと self はサイズ的に不利になるが、as_ref があると self だけで問題なく運用できるようになる。