Pattern Matching
เกินกว่า switch/case
หัวข้อที่มีชื่อว่า “เกินกว่า switch/case”switch ของ TypeScript match ได้ทีละค่าเดียว ส่วน match/case ของ Python (เข้ามาตั้งแต่ 3.10) เป็นแบบ structural คือ destructure sequence, dictionary และ class instance ไปพร้อมกับการ match ได้เลย ลองนึกภาพว่าเป็น switch บวกกับ array/object destructuring หลอมรวมอยู่ใน statement เดียว
Sequence patterns
หัวข้อที่มีชื่อว่า “Sequence patterns”// TypeScript — switch + destructuringconst command = ["move", 10, 20];
if (Array.isArray(command) && command[0] === "move") { const [, x, y] = command; console.log(`Move to (${x}, ${y})`);} else if (command[0] === "stop") { console.log("Stopping");} else { console.log("Unknown command");}command = ["move", 10, 20]
match command: case ["move", x, y]: print(f"Move to ({x}, {y})") case ["stop"]: print("Stopping") case _: print("Unknown command")
# Output: Move to (10, 20)pattern case ["move", x, y] ตรวจสอบความยาว list ตรวจสอบว่า element แรกเท่ากับ "move" และ bind x และ y กับ element ที่สองและสาม — ทั้งหมดในขั้นตอนเดียว
Mapping patterns
หัวข้อที่มีชื่อว่า “Mapping patterns”Mapping patterns match dictionary shapes คล้ายกับ TypeScript object destructuring ใน switch
// TypeScript — discriminated union patterntype Event = | { type: "click"; x: number; y: number } | { type: "keypress"; key: string };
function handle(event: Event) { switch (event.type) { case "click": console.log(`Click at (${event.x}, ${event.y})`); break; case "keypress": console.log(`Key: ${event.key}`); break; }}event = {"type": "click", "x": 100, "y": 200}
match event: case {"type": "click", "x": x, "y": y}: print(f"Click at ({x}, {y})") case {"type": "keypress", "key": key}: print(f"Key pressed: {key}") case _: print("Unknown event")
# Output: Click at (100, 200)Class patterns
หัวข้อที่มีชื่อว่า “Class patterns”Class patterns destructure dataclass (หรือคลาสใดก็ตามที่มี __match_args__) instances
// TypeScript — instanceof + destructuringclass Point { constructor(public x: number, public y: number) {} }
function describe(p: Point): string { if (p.x === 0 && p.y === 0) return "Origin"; if (p.x === 0) return `Y-axis at ${p.y}`; if (p.y === 0) return `X-axis at ${p.x}`; return `At (${p.x}, ${p.y})`;}from dataclasses import dataclass
@dataclassclass Point: x: int y: int
point = Point(0, 5)
match point: case Point(x=0, y=0): print("Origin") case Point(x=0, y=y): print(f"On Y-axis at {y}") case Point(x=x, y=0): print(f"On X-axis at {x}") case Point(x=x, y=y): print(f"At ({x}, {y})")
# Output: On Y-axis at 5Guard conditions (if clauses)
หัวข้อที่มีชื่อว่า “Guard conditions (if clauses)”คุณเพิ่ม if guard ใน case arm ใดก็ได้ — เทียบเท่ากับ conditional switch trick ของ TypeScript
// TypeScript — ไม่มี guard syntax ที่สะอาดใน switchfunction grade(score: number): string { if (score >= 90) return "A"; if (score >= 80) return "B"; if (score >= 70) return "C"; return "F";}def grade(score: int) -> str: match score: case s if s >= 90: return "A" case s if s >= 80: return "B" case s if s >= 70: return "C" case _: return "F"
print(grade(85)) # Bลองเล่น
หัวข้อที่มีชื่อว่า “ลองเล่น”from dataclasses import dataclass
@dataclassclass Point: x: int y: int
# Sequence patternfor cmd in [["move", 5, 10], ["stop"], ["jump", 3], ["move", 0, 0]]: match cmd: case ["move", x, y]: print(f" move -> ({x}, {y})") case ["stop"]: print(" stop") case _: print(f" unknown: {cmd}")
print()
# Mapping patternevents = [ {"type": "click", "x": 10, "y": 20}, {"type": "keypress", "key": "Enter"}, {"type": "resize", "w": 800, "h": 600},]for evt in events: match evt: case {"type": "click", "x": x, "y": y}: print(f" click ({x},{y})") case {"type": "keypress", "key": k}: print(f" key: {k}") case {"type": t}: print(f" other event: {t}")
print()
# Class pattern with guardsfor pt in [Point(0, 0), Point(0, 7), Point(3, 0), Point(3, 4)]: match pt: case Point(x=0, y=0): print(" origin") case Point(x=0, y=y) if y > 0: print(f" +Y axis at {y}") case Point(x=x, y=0) if x > 0: print(f" +X axis at {x}") case Point(x=x, y=y): print(f" quadrant ({x},{y})")Loading Python runtime (first run only)…