Enums
Using enums to define different variants.
Enums
An enum allows us to define a type that can have multiple possible variants.
Basic Enum
RUSTenum IpAddrKind { V4, V6, }
Using Enums
RUSTlet four = IpAddrKind::V4; let six = IpAddrKind::V6;
Enums with Data
RUSTenum IpAddr { V4(String), V6(String), } let home = IpAddr::V4(String::from("127.0.0.1"));
Different Types of Data
RUSTenum IpAddr { V4(u8, u8, u8, u8), V6(String), }
Option Enum
Rust has no null! Instead, we use the Option<T> enum:
RUSTenum Option<T> { Some(T), None, } let some_number = Some(5); let absent_number: Option<i32> = None;
Match Expression
RUSTmatch some_value { IpAddr::V4(addr) => println!("IPv4: {}", addr), IpAddr::V6(addr) => println!("IPv6: {}", addr), }
Code Examples
Basic Enum
Enum definition and usage
enum IpAddrKind {
V4,
V6,
}
fn main() {
let four = IpAddrKind::V4;
let six = IpAddrKind::V6;
route(four);
route(six);
}
fn route(ip_kind: IpAddrKind) {
match ip_kind {
IpAddrKind::V4 => println!("IPv4 address"),
IpAddrKind::V6 => println!("IPv6 address"),
}
}Explanation:
An enum allows us to define a type with multiple possible values. We reference enum variants with the `::` syntax.
Enum with Data
Enum variants with data
enum IpAddr {
V4(String),
V6(String),
}
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(i32, i32, i32),
}
fn main() {
let home = IpAddr::V4(String::from("127.0.0.1"));
let loopback = IpAddr::V6(String::from("::1"));
let msg = Message::Move { x: 10, y: 20 };
}Explanation:
Enum variants can contain data. This allows us to store different types and amounts of data in each variant.
Option Enum
Using Option instead of null
fn main() {
let some_number = Some(5);
let some_string = Some("a string");
let absent_number: Option<i32> = None;
match some_number {
Some(value) => println!("Value: {}", value),
None => println!("No value"),
}
}Explanation:
The Option<T> enum is Rust's way of handling null values. Some(T) contains a value, None indicates no value.
Blockchain: Transaction Type Enum
Using enums for different transaction types
enum TransactionType {
Transfer { from: String, to: String, amount: u64 },
ContractCall { contract: String, method: String, args: Vec<String> },
Stake { validator: String, amount: u64 },
Unstake { validator: String, amount: u64 },
}
fn process_transaction(tx: TransactionType) {
match tx {
TransactionType::Transfer { from, to, amount } => {
println!("Transfer {} tokens from {} to {}", amount, from, to);
},
TransactionType::ContractCall { contract, method, args } => {
println!("Calling {}.{} with {:?}", contract, method, args);
},
TransactionType::Stake { validator, amount } => {
println!("Staking {} tokens to validator {}", amount, validator);
},
TransactionType::Unstake { validator, amount } => {
println!("Unstaking {} tokens from validator {}", amount, validator);
},
}
}
fn main() {
let tx1 = TransactionType::Transfer {
from: String::from("0xAlice"),
to: String::from("0xBob"),
amount: 100,
};
process_transaction(tx1);
let tx2 = TransactionType::Stake {
validator: String::from("0xValidator1"),
amount: 1000,
};
process_transaction(tx2);
}Explanation:
Enums are perfect for representing different transaction types in blockchain. Each variant can hold different data, and pattern matching handles each type safely.
Blockchain: Block Status Enum
Using enums for block states
enum BlockStatus {
Pending,
Confirmed { confirmations: u32 },
Orphaned,
Finalized,
}
fn get_status_message(status: BlockStatus) -> String {
match status {
BlockStatus::Pending => String::from("Block is pending confirmation"),
BlockStatus::Confirmed { confirmations } => {
format!("Block confirmed with {} confirmations", confirmations)
},
BlockStatus::Orphaned => String::from("Block was orphaned (not in main chain)"),
BlockStatus::Finalized => String::from("Block is finalized (cannot be reverted)"),
}
}
fn main() {
let status1 = BlockStatus::Pending;
let status2 = BlockStatus::Confirmed { confirmations: 6 };
println!("{}", get_status_message(status1));
println!("{}", get_status_message(status2));
}Explanation:
Block status can be represented as an enum. This makes the state explicit and prevents invalid states. Pattern matching ensures all cases are handled.
Exercises
Creating an Enum
Create a Direction enum with North, South, East, West variants!
Starter Code:
fn main() {
}Blockchain: Transaction Status
Create a TransactionStatus enum for blockchain!
Starter Code:
fn main() {
}