ปูต้นฉบับหนีบตั๋วสองใบให้เดินทางเป็นคู่ ขณะที่ตั๋วเดี่ยวถูกพักไว้

Rust Option::zip: รวมค่าที่ต้องมาคู่กันโดยไม่ซ่อนสถานะขาดครึ่ง

พี่โชว์Engineering

ข้อมูลตั้งค่าหลายชุดมีค่าที่ต้องมาพร้อมกัน เช่นเวลาเริ่มกับเวลาจบ ถ้าเขียน if let ซ้อนกัน เราอาจเผลอทำให้กรณีมีเพียงฝั่งเดียวดูเหมือน “ไม่ตั้งค่า” Option::zip รวมสอง Option เป็น Some((a, b)) เฉพาะเมื่อทั้งคู่มีค่าครับ

WHY: บังคับคู่ก่อนตรวจความสัมพันธ์

เหมือนคูปองหมูกระทะที่ต้องมีทั้งบัตรโต๊ะและบัตรเวลา ขาดใบใดใบหนึ่งไม่ใช่ชุดใช้งานได้ แต่ “ขาดทั้งคู่” อาจหมายถึงใช้ค่า default เราจึงควรแยกสถานะขาดครึ่งออกจากช่วงที่ค่าครบแต่ลำดับผิด

#[derive(Debug, PartialEq)]
enum WindowError { Incomplete, Reversed }

fn window(start: Option<u32>, end: Option<u32>) -> Result<Option<(u32, u32)>, WindowError> {
    match (start, end) {
        (None, None) => Ok(None),
        (Some(_), None) | (None, Some(_)) => Err(WindowError::Incomplete),
        (start, end) => {
            let (start, end) = start.zip(end).expect("both variants are Some");
            if start > end { Err(WindowError::Reversed) } else { Ok(Some((start, end))) }
        }
    }
}

#[test]
fn preserves_missing_and_invalid_states() {
    assert_eq!(window(None, None), Ok(None));
    assert_eq!(window(Some(8), Some(17)), Ok(Some((8, 17))));
    assert_eq!(window(Some(8), None), Err(WindowError::Incomplete));
    assert_eq!(window(Some(18), Some(17)), Err(WindowError::Reversed));
}

HOW: zip ไม่ได้ validate ค่า

zip ทำหน้าที่แค่รวม presence มันไม่รู้ว่า start <= end หรือค่าตรง schema หรือไม่ จึงเหมาะกับขั้นแรกของ pipeline แล้วค่อยใช้ filter, and_then หรือ Result อธิบายเหตุผลที่ปฏิเสธ ตัวอย่างเลือก match ก่อนเพื่อรักษาความต่างระหว่าง “ไม่ตั้งทั้งคู่” กับ “ส่งมาไม่ครบ”

ถ้าธุรกิจยอมให้มีฝั่งเดียวจริง อย่าฝืน zip เพราะมันจะทิ้งค่านั้นเป็น None แบบเงียบ ๆ สร้าง enum เช่น Unbounded, From, Until, Between จะสื่อ state ได้ดีกว่า ส่วน zip_with ยังไม่ stable ในทุก toolchain ที่ใช้งานทั่วไป จึงไม่ควรผูกบทความกับ API ที่ยังต้อง feature gate

Recap

  • ใช้ zip เมื่อสองค่า meaningful เฉพาะตอนมีพร้อมกัน
  • แยก absent-both, incomplete และ invalid-value ให้ชัด
  • อย่าคิดว่า zip ตรวจ business rule ให้แล้ว
  • ถ้ามีสถานะมากกว่าสองแบบ ใช้ enum แทนคู่ Option
  • ทดสอบครบทั้ง four-way presence matrix