Option and default
- Rust course
- Intermediate
- Lesson 105/115
- 4 min
Learn Option fields and default values.
Option and default
In real data some fields may be missing. Option<T> fields become None if missing; #[serde(default)] puts the type's default into a missing field. When writing, skip_serializing_if is used to skip None fields:
#[derive(Serialize, Deserialize)]
struct Profil {
ad: String,
#[serde(skip_serializing_if = "Option::is_none")]
sehir: Option<String>,
#[serde(default)]
puan: u32, // 0 if missing from the JSON
}Skipping by hand
To build the same behaviour by hand, we collect the fields in a list and add only the filled ones:
fn json(&self) -> String {
let mut alanlar = vec![format!("\"ad\":\"{}\"", self.ad)];
if let Some(s) = &self.sehir {
alanlar.push(format!("\"sehir\":\"{}\"", s));
}
format!("{{{}}}", alanlar.join(","))
}format!("{{{}}}", ..): the outer {{ and }} are literal braces, the middle {} is a placeholder.
Practice Optional city
Write the json method above for Profil { ad: String, sehir: Option<String> }, skipping a None city. Print the profiles Ece (no city) and Can (İzmir) on separate lines.
Starter code
fn main() {
// buraya yaz
}Sample solution
struct Profil {
ad: String,
sehir: Option<String>,
}
impl Profil {
fn json(&self) -> String {
let mut alanlar = vec![format!("\"ad\":\"{}\"", self.ad)];
if let Some(s) = &self.sehir {
alanlar.push(format!("\"sehir\":\"{}\"", s));
}
format!("{{{}}}", alanlar.join(","))
}
}
fn main() {
let a = Profil { ad: "Ece".into(), sehir: None };
let b = Profil { ad: "Can".into(), sehir: Some("İzmir".into()) };
println!("{}", a.json());
println!("{}", b.json());
}Expected output
{"ad":"Ece"}
{"ad":"Can","sehir":"İzmir"}
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Without <code>skip_serializing_if</code>, how is <code>sehir: None</code> written?
- It errors
- "sehir":null Correct answer
- It isn't written at all
- "sehir":""
Explanation: serde turns None into JSON null; skipping the field entirely needs skip_serializing_if.
2 Default value
#[serde(____)]
puan: u32, // JSON'da yoksa 0
#[serde(default)]
puan: u32, // JSON'da yoksa 0
Explanation: #[serde(default)] puts Default::default() into a missing field.
3 Attribute and effect
| Term | Meaning |
|---|---|
Option<T> |
None if missing |
#[serde(default)] |
Default if missing |
skip_serializing_if |
Skip by condition |
#[serde(skip)] |
Never write/read |