I think it's important to point out that as_ref really can be different methods.
-
AsRef::<Target>::as_refas implemented byimpl AsRef<str> for <String>impl AsRef<str> for <str>impl AsRef<[u8]> for <str>- and many others
Option::as_refResult::as_ref
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:
-
&xturns a value into a reference to that value. - Calling
.as_ref()on a value (or reference to a value) of a typeUthat implements theAsRef<T>trait will perform a cheap conversion from&Uto&T. - Calling
.as_ref()on an&Option<T>or&Result<T, E>will convert them into an ownedOption<&T>orResult<&T, &E>.
Pretty confusing
.