Rust does not use exceptions. Instead, it employs the Result<T, E> type for handling recoverable errors and the panic! macro to halt execution when an unrecoverable error occurs.
What are Result and Option enums in Rust?
Key takeaways:
Result enum represents operations that can succeed or fail, with variants
Ok(T)for success andErr(E)for errors.Option enum is used to indicate the presence or absence of a value, with variants
Some(T)for a value andNonefor no value.
Resultenables graceful error management, allowing functions to return errors without crashing the program.
Optionsimplifies handling scenarios where a value might not exist, promoting safer code practices.Both enums enhance Rust's type safety by enforcing explicit handling of success and failure cases at compile time.
Rust is a modern systems programming language known for its focus on safety, performance, and concurrency. It features a powerful type system that prevents common programming errors at compile time, such as null pointer dereferences and data races.
Enums, one of Rust's key language constructs, allow developers to define custom types with a fixed set of possible values, making code more expressive and type-safe. Let's explore enums in Rust and how they enhance the language's expressiveness and safety.
Built-in enums
We can create enums of our own, but Rust offers the following enums that are built into the language that we can make use of. They are as follows:
The
ResultenumThe
Optionenum
Let's explore in detail the functionality of the two.
The Result enum
The Result enum is used for functions that can return either a successful value or an error. Result is commonly used for operations that can fail, such as file I/O, network requests, or any operation that may result in an error. It has two variants:
The
Okvariant: This variant is used to denote the successful execution of code and is also returned in such cases.The
Errvariant: This variant is used for error handling and is used to return errors instead of halting program execution.
For example we can have a function return two different types of variables by using the Result enum. Let's consider a scenario where we want a function to return an error if the value of a variable passed in it is less than five.
Otherwise, it will return the same number.
fn return_result(number: i32) -> Result<i32, String>{if number >= 5 {Ok(number)} else {Err("Number is less than five!".to_string())}}fn main(){let x: i32 = 1;match return_result(x) {Ok(result) => println!("{}", result),Err (e) => println!("{}", e)}}
In the code shown above, we've created two functions:
Lines 1–7: This is the function in which we'll use the
Resultenum to return two different types of variables.Line 1: Let's talk about the function signature first. It takes in an unsigned integer and returns a
Resultwith the following two generics:i32String
Lines 2–6: This
ifcondition checks if the number is less than or greater than five and returns theResultenum's variants accordingly.Line 3: If the number is greater than or equal to five, then the
return_result()function returns the number wrapped in theOkvariant.Line 5: If the number is less than five, then the
return_result()function returns aString.
Lines 10–17: This is our
main()function will get executed when we run the program.Line 11: Here, we declare the variable that we'll pass into the function.
Lines 13–16: This is the
matchstatement which handles the different kinds of values returned by thereturn_result()function.
Note: The
Resultenum is usually better in cases when the function has to return either it's intended value or an error. This allows us to catch errors without stopping program execution.
The Option enum
Option is commonly used in situations where a value may or may not be present. For example, when searching for an item in a collection. The Option enum has two variants:
The
Somevariant contains a value of typeT.The
Nonevariant indicates the absence of a value.
This enum is used to handle cases where there is no value present. Let's consider the same scenario for this enum as well. We'll use this inside a function that will either return a variable of a certain type, or return the variant of type.
fn return_option(number: i32) -> Option<i32> {if number >= 5 {Some(number)} else {None}}fn main(){let x: i32 = 5;match return_option(x) {Some(option) => println!("{}", option),None => println!("None!")}}
Let's take a look at the code shown above:
Lines 1–7: This is the
return_option()function that we'll use to return theOptionenum.Lines 2–7: This
ifblock checks if the number being passed into the function is less than or equal to five.Line 3: If it is greater than or equal to five, the function will return
numberwrapped into theSomevariant of the enum.Line 5: If it is less than five, the function will return a
Noneobject which has no type.
Lines 10–17: This is our
main()function that gets called when we execute the code.Line 11: This is the variable we'll use to test out the
return_option()function.Lines 13–16: This
matchstatement handles the variants returned by thereturn_option()function.
Note: We can use the
Optionenum for error handling as well. The absence of value simple makes us handle the specific case where the expected value was not returned.
Result and Option enums
Key differences |
|
|
Purpose | Represents success or error | Represents optionality |
Variants |
|
|
Error handling | No error information | Contains error type |
Conclusion
Enums represent a powerful language construct in Rust, enabling developers to define custom types with fixed sets of possible values.
By exploring built-in enums like Result and Option, developers can handle errors and represent absence or presence of values effectively. These language features contribute to Rust's expressiveness, safety, and suitability for building robust and scalable systems.
Frequently asked questions
Haven’t found what you were looking for? Contact Us
What is the difference between Rust result and exception?
What is a Rust panic?
Is enum better than array?
Free Resources