ข้ามไปยังเนื้อหา

Pattern Matching

switch ของ TypeScript match ได้ทีละค่าเดียว ส่วน match/case ของ Python (เข้ามาตั้งแต่ 3.10) เป็นแบบ structural คือ destructure sequence, dictionary และ class instance ไปพร้อมกับการ match ได้เลย ลองนึกภาพว่าเป็น switch บวกกับ array/object destructuring หลอมรวมอยู่ใน statement เดียว

TypeScript
// TypeScript — switch + destructuring
const 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");
}
Python
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 match dictionary shapes คล้ายกับ TypeScript object destructuring ใน switch

TypeScript
// TypeScript — discriminated union pattern
type 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;
}
}
Python
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 destructure dataclass (หรือคลาสใดก็ตามที่มี __match_args__) instances

TypeScript
// TypeScript — instanceof + destructuring
class 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})`;
}
Python
from dataclasses import dataclass
@dataclass
class 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 5

คุณเพิ่ม if guard ใน case arm ใดก็ได้ — เทียบเท่ากับ conditional switch trick ของ TypeScript

TypeScript
// TypeScript — ไม่มี guard syntax ที่สะอาดใน switch
function grade(score: number): string {
if (score >= 90) return "A";
if (score >= 80) return "B";
if (score >= 70) return "C";
return "F";
}
Python
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
@dataclass
class Point:
x: int
y: int
# Sequence pattern
for 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 pattern
events = [
{"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 guards
for 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})")
Python เวอร์ชันใดที่ introduce structural pattern matching?
ใน `case ["move", x, y]` `x` ทำอะไร?
จะเพิ่ม conditional check ใน case arm ได้อย่างไร?
`case _:` match อะไร?