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

Option and Result

TypeScript ใช้ T | null | undefined สำหรับค่าที่อาจมีหรือไม่มี และใช้ try/catch สำหรับ error ส่วน Rust เข้ารหัสทั้งสองอย่างไว้ในระบบ type:

  • Option<T> — เป็นได้ทั้ง Some(value) หรือ None ไม่มี null ไม่มี undefined
  • Result<T, E> — เป็นได้ทั้ง Ok(value) หรือ Err(error) ไม่มี exception

ระบบ type บังคับให้คุณจัดการทั้งสองกรณีก่อนที่จะใช้ค่าได้

// TypeScript: null can silently propagate
function findUser(id: number): User | null { ... }
const user = findUser(42);
console.log(user.name); // runtime crash if null
// Rust: the compiler won't let you use the value without handling None
fn find_user(id: u32) -> Option<User> { ... }
match find_user(42) {
Some(user) => println!("{}", user.name),
None => println!("not found"),
}
// TypeScript: error can be thrown anywhere
function divide(a: number, b: number): number {
if (b === 0) throw new Error("division by zero");
return a / b;
}
// Rust: error is part of the return type
fn divide(a: f64, b: f64) -> Result<f64, String> {
if b == 0.0 { Err("division by zero".to_string()) }
else { Ok(a / b) }
}
TypeScriptRust
value ?? defaultValoption.unwrap_or(defaultVal)
value! (non-null assertion)option.unwrap() (panic ถ้าเป็น None)
value ?? (() => { throw ... })()option.expect("msg") (panic พร้อมข้อความ)

ใน function ที่ return Result นั้น ? บนค่า Result จะ unwrap Ok ให้ หรือไม่ก็ return Err ออกไปก่อนกำหนด — ช่วยตัดการซ้อน match หลายชั้นออกไป:

fn read_number(s: &str) -> Result<i32, std::num::ParseIntError> {
let n = s.trim().parse::<i32>()?; // returns Err early if parse fails
Ok(n * 2)
}
TypeScript
// Option-like: null / undefined
function divide(a: number, b: number): number | null {
if (b === 0) return null;
return a / b;
}
const r = divide(10, 2) ?? 0;
console.log(r); // 5
// Error handling: try/catch
try {
const val = JSON.parse("bad json");
} catch (e) {
console.error("parse error", e);
}
Rust
fn divide(a: f64, b: f64) -> Result<f64, String> {
if b == 0.0 {
Err(String::from("division by zero"))
} else {
Ok(a / b)
}
}
fn main() {
match divide(10.0, 2.0) {
Ok(v) => println!("{v}"), // 5
Err(e) => println!("{e}"),
}
let maybe: Option<i32> = Some(42);
let value = maybe.unwrap_or(0);
println!("{value}"); // 42
}
fn divide(a: f64, b: f64) -> Result<f64, String> {
if b == 0.0 {
Err(String::from("division by zero"))
} else {
Ok(a / b)
}
}
fn main() {
match divide(10.0, 2.0) {
Ok(result) => println!("10 / 2 = {result}"),
Err(e) => println!("Error: {e}"),
}
match divide(5.0, 0.0) {
Ok(result) => println!("5 / 0 = {result}"),
Err(e) => println!("Error: {e}"),
}
let maybe: Option<i32> = Some(42);
let value = maybe.unwrap_or(0);
println!("Option value: {value}");
}
`Option<T>` แทนอะไรใน Rust?
operator `?` ทำอะไรกับ `Result` ใน Rust?
method ตัวไหนคืนค่า default เมื่อ Option เป็น None?