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 https://www.fpcomplete.com/blog/rust-asref-asderef/, 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.