what is the different with Option as_ref and as_deref in Rust

Now I am using the rust code snippet like this:

let stackoverflow = format!("{}{}{}","\\social[stackoverflow]{",request.cv_main.stackoverflow.as_deref().unwrap_or_default(),"}\n");

and this is the request cv_main defined:

use serde::{Deserialize, Serialize};

use super::{edu::edu::CvEduResp, work::cv_work_resp::CvWorkResp};

#[derive(Serialize, Deserialize, Default, Clone)]
pub struct CvMainResp {
    pub id: i64,
    pub cv_name: String,
    pub created_time: i64,
    pub updated_time: i64,
    pub user_id: i64,
    pub cv_status: i32,
    pub template_id: i64,
    pub employee_name: Option<String>,
    pub birthday: Option<String>,
    pub phone: Option<String>,
    pub email: Option<String>,
    pub stackoverflow: Option<String>,
    pub github: Option<String>,
    pub blog: Option<String>,
    pub edu: Option<Vec<CvEduResp>>,
    pub work: Option<Vec<CvWorkResp>>,

this code works fine, but I am still could not understand why here need to use as_deref(). I have read the article, still did not figure out. does there any simple explain the different with as_ref and as_deref?


  • Called on an Option<String>, as_ref() returns an Option<&String>. as_deref() on the other hand returns Option<&str>, which you could also obtained with .map(|s| s.as_str()) or .map(|s| &*s). (The latter is generally equivalent to as_deref(), and demonstrates String "dereferencing" into str, which is why it's called as_deref().)

    While Option<&String> and Option<&str> are functionally similar, they are not exactly the same. Here the point of as_deref() is to be able to chain it to .unwrap_or_default().

    unwrap_or_default() can be called on Option<&str> because &str implements Default, <&str as Default>::default() just returns the reference to a statically allocated "" singleton. On the other hand, Default is not implemented for &String, because it would have to return a reference to a String that outlives it, which is not allowed by the borrow checker.