• Deref trait is used for immutable dereferncing operation.
pub trait Deref {
    type Target: ?Sized;

    // Required method
    fn deref(&self) -> &Self::Target;
}
  • Deref coercion → T: Deref<Target = U> and let v: T

    • *v is equivalent to *Deref::deref(&v) (immutable contexts)
    • values of type &T are coerced to values of type &U
    • T implicitly implements all the methods of the U which take the &self receiver
  • Using with Option<Box<T>>

v: Option<Box<T>>
v.as_ref(): Option<&Box<T>>
v.as_deref(): Option<&T>

pub const fn as_ref(&self) -> Option<&T>
pub fn as_mut(&mut self) -> Option<&mut T>
pub fn as_deref(&self) -> Option<&<T as Deref>::Target>
pub fn as_deref_mut(&mut self) -> Option<&mut <T as Deref>::Target>
pub fn as_pin_ref(self: Pin<&Option<T>>) -> Option<Pin<&T>>
pub fn as_slice(&self) -> &[T]
pub fn as_mut_slice(&mut self) -> &mut [T]
  • Strings! → Deref<Target = str>

String exposes as_str() through Deref, which is why you can call all str methods on a String. Deref exposes the string slice through the a bit awkward &*s syntax, so another way to obtain Option<&str> is opt.as_ref().map(|s| &*s). This will work in generic code where as_str() is not available.

Option::as_deref() is a short-hand for that - called on Option<String>, it will return Option<&str>. Called on Option<Vec<u8>> will return Option<&[u8]>, and so on.