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).
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
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.