What is enum
Enums are User defined data type(Similar to other languages) which can
be assigned some limited values. In rust enum variable can/cannot hold
the data (Eg: String).
C++ enums are named integer constants, whereas Rust enums are Data Types
that can carry distinct payloads of data per variant
Properties of enum in Rust
| Property | Description |
|---|---|
| Individual variants can contain completely different types of data |
|
| Attach behavior directly to your enums using impl blocks |
|
| Safety via Exhaustive Pattern Matching |
Rust forces you to account for every single enum variant using the
match keyword. Leaving out a variant causes a compile-time failure,
preventing unintended runtime edge cases. wrt C++. While a modern C++ compiler can generate warnings for unhandled cases inside a switch statement on an enum class, it will still compile and run. |
| Specialized optimizations |
Because the Rust compiler understands the exact layout of its enums,
it performs specialized optimizations. |
enum types
1. Not holding data
#[derive(Debug)] //To print debugging information
enum Color{ //Declare enum
Red,
Blue,
Green
}
fn fun (a:Color) { //Print enum after passing to function
println!("{:#?}",a);
}
fn main() {
let a:Color = Color::Red; //Initialize variable with enum value
fun(a);
}
2. Enum Holding the data
// Enum holding 1 datatype
use std::{string::String, u32};
#[derive(Debug)]
enum Address{ //1. Enum variable storing string data
IPv4(String),
IPv6(String),
}
fn fun (addr:&Address) { //3. Passing enum variable to function and print
println!("{:#?}",addr);
}
fn main() {
let router1:Address =
Address::IPv4(String::from("192.168.1.1")); //2. Creating enum variable having string data(192.168.1.1)
fun(&router1);
}
# rustc test.rs
# ./test.exe
IPv4(
"192.168.1.1",
)
// Enum Holding Multiple Datatypes
use std::{string::String, u32};
#[derive(Debug)]
enum Address{ //1. Enum data structure holding 3 variables
NoIP, //NoIP does not hold any data
IPv4(u8,u8,u8,u8), //IPv4 holding 4 u8 types
IPv6(String), //IPv6 holding String type
}
/*THIS IS EQUIVALENT TO:
struct NoIP;
struct IPv4 {
a: i32,
b: i32,
c: i32,
d: i32,
}
struct IPv6 {
e:String
}
*/
fn fun (addr1:&Address,addr2:Address, addr3:Address) { //3. Printing enum variables
println!("IPv4 {:#?}",addr1);
println!("IPv6 {:#?}",addr2);
println!("Disconnected {:#?}",addr3);
}
fn main() {
let router1:Address =
Address::IPv4(10,11,12,13); //2. Router1 variable type=IPv4
let router2:Address = Address::IPv6(String::from("::1")); //router2 of IPv6
let disconnectedDevice:Address = Address::NoIP; //disconnectedIP of no ip
fun(&router1,router2);
}
# rustc test.rs
# .\test.exe
IPv4 IPv4(
10,
11,
12,
13,
)
IPv6 IPv6(
"::1",
)
Disconnected NoIP
Option Enum = NULL
The Option enum in Rust is a built-in generic type used to represent a
value that may or may not be present.
Because Rust does not have a null value like many other
programming languages, it relies on the Option type to safely encode the
concept of "nothingness" without risking null pointer
Usage of Option Enum:
Preventing Null Pointer Exceptions: In other languages, forgetting to
check for null can crash your application at runtime. Rust forces you to
acknowledge the None variant via the compiler, guaranteeing safety.
Syntax
|
|
enum Option <T> { //T is template which can take any type: i32, i64 etc
Some (T),
None,
}
1. Initializing and using Option <T>
fn main() {
let a : Option <i32> = Some(2);
let b : Option <i32> = None;
println! ("a:{:#?}",a);
println! ("b:{:#?}",b);
}
$ ./main.exe
a : Some(
2,
)
b : None
2. Option <T> cannot be added to non-Option <T>
fn main() {
let x: i8 = 5;
let y: Option <i8> = Some(5);
let sum = x + y; //Compliation Error
}
Creating NULL was mistake?
Tony Hoare(inventor of NULL) said invention of NULL is his Billion
dollar mistake. Why?
Using NULL value as non-NULL value. Eg: derefercing NULL ptr. It will
crash. Problem is not in NULL but at places it gets misused.
There are multiple situations, where crash is caused due to NULL.
Example: NULL References when derefrenced will cause crash
int fun(struct A*& p){ //Funtion taking NULL reference
if (p == nullptr)
cout << "Got Null ptr reference\n";
cout << p->a;
}
int main(){
struct A* p = nullptr;
fun(p);
}
$ ./a.out
Got Null ptr reference
Segmentation Fault
How Rust avoid Null ptr?
-
1. Variable that can have NULL/other value is declared as Option
<T>
2. Rust does not allow creating structure object without initializing its members. It can be initialized with Some or None. No crash, None will be printed.