Option Enum used to represent a value that can be either present(Some(T)) or absent(None)
Option<T>
Enum has two Variants.
Option<T>{
None,
Some(T)
}
where, Some(T) -> Used to represent value(T is a generic type here - It can be any type) None -> Used when the value is absent
Here's the simple example of using Option Enum.
struct User {
full_name: String,
nickname: Option<String>
}
impl User {
fn get_user_nickname(&self) -> String {
match &self.nickname {
Some(nickname) => nickname.clone(),
None => "doesn't have a nick name".to_string()
}
}
}
fn main() {
let michael = User {
full_name: "Michael".to_string(),
nickname: Some("Mike".to_string())
};
println!("Michael nick name is {} ",michael.get_user_nickname());
let john = User {
full_name: "John".to_string(),
nickname: None,
};
println!("John {}", john.get_user_nickname());
}
Here, I defined the nickname field in User struct as a Option Enum. So, nickname field can be None, in such cases where a user don't have a nick name.
Then, I use Some and None variants of Option Enum for nickname field according to the need, when I declare the User struct, and the output.
Michael nickname is Mike
John doesn't have a nickname
So, We can use Option Enum where we unsure whether the value present or not(null).
Impl Methods
Option Enum has several impl methods, It helps to work with Option Enum. Here, We will see some common methods.
is_some and is_none
We can use is_some and is_none methods to check whether our option variable contains value or not. Let's consider below example,
fn main() {
let number: Option<i32> = Some(43);
println!("{}", number.is_some()); // true
let number: Option<i32> = None;
println!("{}", number.is_none()); // true
}
is_some method will return true if our option variable contains a value.
Likewise, is_none method will return true if our option variable contains a absence of a value.
as_ref
as_ref method gives access to reference of the Option type. For example,
let name: Option<String> = Some(String::from("John"));
let ref_name: Option<&String> = name.as_ref();
Here, as_ref method converts Option<T> type to Option<&T> .
We can use as_ref() when we only need to borrow the value of Option variable instead of taking ownership of it.
unwrap
unwrap() is used to retrieve the Some(value) value from the Option Type. unwrap will panic if we use againt `None` value
let number = Some(32);
println!("{:?}", number); // Some(32)
let number = number.unwrap();
println!("{}", number); // 32
let not_number: Option<i32> = None;
let not_number = not_number.unwrap(); // It will panic
Be sure to with unwrap, as it will panic if the Option is None. It's recommended to use it only when you're sure that the Option will contain a value.
unwrap_or_else
In, unwrap_or_else, If option has value it will return the value. If Option is None, it will call the closure.
let number: Option<i32> = None;
println!("number {:?}", number); // number None
let number = number.unwrap_or_else(|| 5);
println!("number {}", number); // number 5
Here, We defined the None variant. So, unwrap_or_else closure will be called and return the value
Conclusion