Enum แบบ Algebraic Data Type
TypeScript union เป็น structural — Rust enum พก data
หัวข้อที่มีชื่อว่า “TypeScript union เป็น structural — Rust enum พก data”TypeScript มี union type ("circle" | "rectangle") และ discriminated union (object ที่มี field kind) พวกนี้ทรงพลัง แต่เป็น convention — compiler เชื่อว่าคุณ set discriminant ถูกต้อง
Rust enum เป็น algebraic data type (ADT) แต่ละ variant พก data ของตัวเองได้ — ต่าง type ต่าง variant Compiler บังคับ exhaustive pattern matching: ถ้าคุณเพิ่ม variant ใหม่ ทุก match ในโค้ดที่ handle enum นั้นต้องอัปเดตด้วย มิฉะนั้นโค้ดจะ compile ไม่ได้
Enum ที่พก data
หัวข้อที่มีชื่อว่า “Enum ที่พก data”// TypeScript — discriminated union (convention-based)type Shape = | { kind: "circle"; radius: number } | { kind: "rectangle"; width: number; height: number } | { kind: "triangle"; base: number; height: number };
function area(shape: Shape): number { switch (shape.kind) { case "circle": return Math.PI * shape.radius ** 2; case "rectangle": return shape.width * shape.height; case "triangle": return 0.5 * shape.base * shape.height; // ถ้าเพิ่ม variant แล้วลืม case TypeScript // จะ warn เฉพาะเมื่อใช้ never-check pattern }}#[derive(Debug)]enum Shape { Circle(f64), Rectangle(f64, f64), Triangle { base: f64, height: f64 },}
impl Shape { fn area(&self) -> f64 { match self { Shape::Circle(r) => std::f64::consts::PI * r * r, Shape::Rectangle(w, h) => w * h, Shape::Triangle { base, height } => 0.5 * base * height, } }}
fn main() { let shapes = vec![ Shape::Circle(3.0), Shape::Rectangle(4.0, 5.0), Shape::Triangle { base: 6.0, height: 4.0 }, ]; for s in &shapes { println!("{:?} => area = {:.2}", s, s.area()); }}Enum สำหรับ state machine
หัวข้อที่มีชื่อว่า “Enum สำหรับ state machine”Enum เป็นวิธี idiomatic ในการ model state machine ใน Rust แต่ละ state variant พก data ที่เกี่ยวข้องกับ state นั้นเท่านั้น:
// TypeScript — state machine ด้วย discriminated uniontype ConnectionState = | { status: "disconnected" } | { status: "connecting"; attempt: number } | { status: "connected"; sessionId: string };
function describe(state: ConnectionState): string { switch (state.status) { case "disconnected": return "not connected"; case "connecting": return `attempt ${state.attempt}`; case "connected": return `session ${state.sessionId}`; }}enum ConnectionState { Disconnected, Connecting { attempt: u32 }, Connected { session_id: String },}
fn describe(state: &ConnectionState) -> String { match state { ConnectionState::Disconnected => "not connected".to_string(), ConnectionState::Connecting { attempt } => format!("attempt {}", attempt), ConnectionState::Connected { session_id } => format!("session {}", session_id), }}
fn main() { let states = vec![ ConnectionState::Disconnected, ConnectionState::Connecting { attempt: 3 }, ConnectionState::Connected { session_id: "abc-123".to_string() }, ]; for s in &states { println!("{}", describe(s)); }}ลองเขียนเอง
หัวข้อที่มีชื่อว่า “ลองเขียนเอง”#[derive(Debug)]enum Shape { Circle(f64), Rectangle(f64, f64), Triangle { base: f64, height: f64 },}
impl Shape { fn area(&self) -> f64 { match self { Shape::Circle(r) => std::f64::consts::PI * r * r, Shape::Rectangle(w, h) => w * h, Shape::Triangle { base, height } => 0.5 * base * height, } }}
fn main() { let shapes = vec![ Shape::Circle(3.0), Shape::Rectangle(4.0, 5.0), Shape::Triangle { base: 6.0, height: 4.0 }, ]; for s in &shapes { println!("{:?} => area = {:.2}", s, s.area()); }}Compiling…