ปูสีส้มแดงต้นฉบับกำลังคัดลูกปัดสีเขียวผ่านช่องวัด โดยมีถาดว่างที่ถือว่าผ่านกฎ

Rust Option::is_none_or: เขียนกฎ ‘ไม่มีก็ได้ มีก็ต้องผ่าน’ ให้ตรงความหมาย

พี่โชว์Engineering

configuration หลายช่องเป็น optional: ถ้าไม่ใส่ให้ใช้ default แต่ถ้าใส่มาต้องอยู่ในขอบเขต เดิมเรามักเขียน value.map(predicate).unwrap_or(true) ซึ่งถูกแต่ต้องแปลในหัวสองชั้น Option::is_none_or เขียนกฎนี้ตรงตัวว่า “เป็น None หรือค่าข้างในผ่าน predicate” ครับ

fn valid_timeout(timeout_ms: Option<u64>) -> bool {
    timeout_ms.is_none_or(|ms| (100..=30_000).contains(&ms))
}

fn main() {
    assert!(valid_timeout(None));
    assert!(valid_timeout(Some(5_000)));
    assert!(!valid_timeout(Some(50)));
    assert!(!valid_timeout(Some(60_000)));
    println!("optional timeout validation passed");
}

เมธอดนี้ consume Option<T> ดังนั้นถ้าต้องใช้ค่าต่อและ T ไม่ใช่ Copy ให้เรียกผ่าน as_ref() เช่น name.as_ref().is_none_or(|s| !s.is_empty()) เพื่อประเมิน Option<&T> แทน การเลือก is_none_or ยังช่วย review เพราะคนอ่านเห็นทันทีว่า None เป็นกรณีที่ยอมรับได้

อย่าสลับกับ is_some_and ซึ่งแปลว่า “ต้องมีค่าและค่านั้นผ่าน” ตัวอย่างช่อง timeout ที่ไม่บังคับใช้ is_none_or; แต่ token ที่ต้องมีและห้ามว่างควรใช้ is_some_and หรือคืน error ที่บอกเหตุผลละเอียดกว่า boolean

Recap

  • ใช้ is_none_or เมื่อ None คือค่า valid
  • ใช้ is_some_and เมื่อการไม่มีค่าต้องตก
  • ผ่าน as_ref() หากยังต้องใช้ค่าที่เป็นเจ้าของต่อ
  • คืน error แทน boolean เมื่อผู้ใช้ต้องรู้เหตุผลที่ไม่ผ่าน