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

基礎知識

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

例えば、Option<T> の as_ref は Option<&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_deref … Deref による参照化
Option<T>
fn as_deref(&self) -> Option<&<T as Deref>::Target>
Result<T>
fn as_deref(&self) -> Result<&<T as Deref>::Target>
as_deref_mut … DerefMut による可変参照化
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_deref と as_deref_mut はそれぞれ as_ref と as_mut の参照からスマートポインタへの一般化である。中でも特によく見るパターンは as_deref による Option<String> から Option<&str> への変換である。

型全体への影響

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

例えば、Option 型の unwrap や map などのメソッドも 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 だけで問題なく運用できるようになる。