14.5 Practical Examples
Let’s examine how Option<T> is applied in typical programming tasks.
14.5.1 Retrieving Data from Collections
Hash maps and other collections often return Option from lookup operations.
use std::collections::HashMap;
fn main() {
let mut scores = HashMap::new();
scores.insert("Alice", 100);
scores.insert("Bob", 95);
let alice_score_option = scores.get("Alice"); // Returns Option<&i32>
match alice_score_option {
Some(&score) => println!("Alice's score: {}", score),
// Note the &score pattern
None => println!("Alice not found."),
}
// Using map to process the score if present
let bob_score_msg = scores.get("Bob") // Option<&i32>
.map(|&score| format!("Bob's score: {}", score)) // Option<String>
.unwrap_or_else(|| "Bob not found.".to_string()); // String
println!("{}", bob_score_msg);
let charlie_score = scores.get("Charlie");
if charlie_score.is_none() {
println!("Charlie's score is not available.");
}
}
Output:
Alice's score: 100
Bob's score: 95
Charlie's score is not available.
14.5.2 Optional Struct Fields
Representing optional configuration or data within structs is a common use case.
struct UserProfile {
user_id: u64,
display_name: String,
email: Option<String>, // Email might not be provided
location: Option<String>, // Location might be optional
}
impl UserProfile {
fn new(id: u64, name: String) -> Self {
UserProfile {
user_id: id,
display_name: name,
email: None,
location: None,
}
}
fn with_email(mut self, email: String) -> Self {
self.email = Some(email);
self
}
fn with_location(mut self, location: String) -> Self {
self.location = Some(location);
self
}
}
fn main() {
let user1 = UserProfile::new(101, "Admin".to_string())
.with_email("admin@example.com".to_string());
println!("User ID: {}", user1.user_id);
println!("Display Name: {}", user1.display_name);
// Use as_deref() to convert Option<String> to Option<&str> before unwrap_or
// This avoids moving the String out and works well with &str default.
println!("Email: {}", user1.email.as_deref().unwrap_or("Not provided"));
// Alternatively, use unwrap_or_else for a String default
println!("Location: {}", user1.location.unwrap_or_else(|| "Unknown".to_string()));
}
Output:
User ID: 101
Display Name: Admin
Email: admin@example.com
Location: Unknown