นากกายต้นฉบับกำลังโยกคันสับรางให้ลูกบอลหนึ่งลูกไปยังถาดผลลัพธ์ที่ถูกต้อง

Java Switch Expressions: ให้ทุกเส้นทางคืนค่าและหยุด Fall-through โดยไม่ตั้งใจ

พี่โชว์Engineering

switch แบบเดิมทำ mapping ได้ แต่ต้องประกาศตัวแปรก่อน assign หลายจุดและระวังลืม break ครับ Switch expression ทำให้ทั้งก้อนเป็นนิพจน์ที่ต้องให้ค่า ช่วยย้ายข้อผิดพลาดจาก runtime มาเป็น compiler error

WHY: Mapping ควรมีผลลัพธ์ครบ

เมื่อ enum เพิ่มค่าใหม่ เราอยากให้จุดแปลงข้อมูลร้องทันที ไม่ใช่เงียบแล้วใช้ค่าเริ่มต้นผิด JEP 361 ทำให้ใช้รูป case ... -> ที่ไม่ fall through และถ้า switch expression บน enum ครบทุกค่าก็ไม่จำเป็นต้องมี default

HOW: คืนค่าตรงหรือใช้ yield ใน Block

public class Main {
    enum Priority { LOW, MEDIUM, HIGH }

    static int retryLimit(Priority priority) {
        return switch (priority) {
            case LOW -> 1;
            case MEDIUM -> 3;
            case HIGH -> {
                int guardedLimit = 5;
                yield guardedLimit;
            }
        };
    }

    public static void main(String[] args) {
        assert retryLimit(Priority.LOW) == 1;
        assert retryLimit(Priority.MEDIUM) == 3;
        assert retryLimit(Priority.HIGH) == 5;
    }
}

ลูกศรเหมาะกับค่าหรือคำสั่งสั้น ถ้าต้องคำนวณหลายบรรทัด ใช้ block แล้ว yield ค่าออกจาก switch อย่าสับสนกับ return ซึ่งออกจากทั้ง method

Default อาจซ่อนการเปลี่ยน Schema

ถ้า selector เป็น enum และทุกค่ามีพฤติกรรมเฉพาะ การใส่ default จะทำให้ compiler ไม่เตือนเมื่อ enum เพิ่มค่า พิจารณาไม่ใส่ default เพื่อให้ build แตกตรงจุดที่ต้องตัดสินใจ แต่ถ้าข้อมูลมาจากขอบระบบและมีค่าที่ไม่รู้จักจริง ให้ parse/validate ที่ boundary ก่อน

Switch expression ไม่แทน polymorphism ทุกกรณี ถ้า mapping กระจายหลายไฟล์และแต่ละชนิดควบคุม behavior เองได้ เมธอดบน enum หรือ sealed hierarchy อาจเหมาะกว่า

Recap

  • ใช้ case -> เพื่อตัด fall-through ที่ไม่ได้ตั้งใจ
  • ใช้ yield เมื่อแต่ละ case ต้องคำนวณหลายบรรทัด
  • ปล่อย enum switch แบบ exhaustive เพื่อให้ compiler เตือนค่าที่เพิ่ม
  • รันด้วย java -ea เพื่อให้ assertion ในตัวอย่างทำงานจริง

พรุ่งนี้เลือก switch ที่ assign ตัวแปรหนึ่งจุด แล้วทดลองย่อให้เป็น expression โดยไม่เปลี่ยนผลลัพธ์ครับ