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?
Option::as_ref()
takes an &Option<String>
and converts it to Option<&String>
. The latter is not the same type as Option<&str>
, the difference being that Option<&String>
always refers to an actual String
, whereas Option<&str>
can refer to string data that is just part of a String
or that is not stored in a heap-allocated String
at all (but in a static constant, for example). For this reason APIs that take strings are encouraged to accept &str
or Option<&str>
rather than &String
or Option<&String>
. Fortunately, when you have an Option<&String>
, you can always convert it to Option<&str>
(but not the other way around).
To convert Option<&String>
returned by as_ref()
to Option<&str>
, you can call opt.as_ref().map(|s| s.as_str())
. String
also exposes as_str()
by implementing Deref
, which is why you can call all str
methods on a String
. Deref
allows the string slice to be accessed through the &*s
syntax, so another way to obtain Option<&str>
is opt.as_ref().map(|s| &*s)
. This slightly awkward syntax has the benefit of working 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.
Finally, while Option<&String>
and Option<&str>
are functionally similar, they are not exactly the same. In the code that is shown, as_deref()
allows the call to .unwrap_or_default()
. unwrap_or_default()
works on Option<&str>
because &str
implements Default
, where <&str as Default>::default()
just returns the reference to a statically allocated ""
singleton. On the other hand, &String
doesn't implement Default
, because it would have to return a reference to a String
that outlives it, which is disallowed by the borrow checker.