What is the difference between as_ref() & '&'?

I think it's important to point out that as_ref really can be different methods.

If I understand it right, then the first isn't the same as the last two, but has the same name.

The first as_ref is doing a cheap conversion from one type to another (more precisely it converts a reference to a value into a reference to a value of a different type), while the last two create an owned Options/Results from a reference to an Option or a Result.


Compare:

pub trait AsRef<T: ?Sized> {
    fn as_ref(&self) -> &T;
}

With:

impl<T> Option<T> {
   pub const fn as_ref(&self) -> Option<&T> {
        match *self {
            Some(ref x) => Some(x),
            None => None,
        }
    }
}

The first one returns a reference (&T), the second one returns an owned value (Option<_>).


So we're talking about three things:

  • &x turns a value into a reference to that value.
  • Calling .as_ref() on a value (or reference to a value) of a type U that implements the AsRef<T> trait will perform a cheap conversion from &U to &T.
  • Calling .as_ref() on an &Option<T> or &Result<T, E> will convert them into an owned Option<&T> or Result<&T, &E>.

Pretty confusing :grin:.