เมื่อ Rust’s Default Trait พบกับปรัชญา Essentialism

Share
เมื่อ Rust’s Default Trait พบกับปรัชญา Essentialism
Photo by Isaac Quesada on Unsplash

ในฐานะโปรแกรมเมอร์ เรามักหมกมุ่นอยู่กับการเปลี่ยนแปลง (Mutation) เราสนใจว่า State จะไหลจาก A ไป B อย่างไร แต่เรามักลืมตั้งคำถามที่สำคัญที่สุดคำถามหนึ่ง:

“ก่อนที่สิ่งนี้จะกลายเป็นสิ่งนั้น… มัน ‘เป็น’ อะไรมาก่อน?”

นี่ไม่ใช่แค่คำถามเชิงตรรกะ แต่มันคือคำถามเชิงปรัชญาที่ลึกซึ้ง และในภาษา Rust คำตอบของคำถามนี้มักจะถูกซ่อนไว้ใน Default trait

สุนทรียศาสตร์ของความว่างเปล่า: นิยามของ ‘แก่นสาร’

ในโลกของปรัชญาตะวันตก มีแนวคิดที่เรียกว่า “Essentialism” ซึ่งเชื่อว่าสรรพสิ่งมี “แก่นสาร” (Essence) ที่ทำให้มันเป็นสิ่งนั้น หากขาดแก่นสารนี้ไป สิ่งนั้นจะสูญเสียอัตลักษณ์ของมันทันที

ลองจินตนาการถึง “เครื่องดื่ม” (Type Drink) แก่นสารของมันคืออะไร? การเป็นของเหลว? การมีรสชาติ? หรือการถูกใช้เพื่อดับกระหาย? ถ้าผมสั่ง "เครื่องดื่ม" จากบาร์เทนเดอร์โดยไม่ระบุเจตจำนง ผมกำลังเรียกหาแก่นสารที่พื้นฐานที่สุดของ Type นั้น

ใน Rust, Default trait ทำหน้าที่แบบเดียวกัน มันคือการประกาศก้องว่า "นี่คือสภาวะพื้นฐานที่สุดที่ฉันดำรงอยู่ได้"

เมื่อคุณเขียนโค้ดนี้:

impl Default for Drink {
fn default() -> Self {
Self {
name: String::from("เหล้าขม"),
cost: 0,
}
}
}

คุณไม่ได้แค่เขียน Function เพื่อคืนค่าเริ่มต้น แต่คุณกำลังนิยามว่า “เครื่องดื่มจำลองในบาร์แห่งนี้มีแก่นแท้คือความขมขื่นที่ราคาถูกที่สุด”

ภัยร้ายของการมีตัวตนโดยบังเอิญ

ความมักง่ายมักนำไปสู่จุดจบที่ไม่สวยงาม นักพัฒนารุ่นใหม่หลายคนเผลอใช้ #[derive(Default)]แปะไว้บนหัว Struct โดยไม่คิดถึงแก่นสารของมัน

#[derive(Default)]
struct User {
id: u64,
name: String,
role: String,
}

ถ้าตาม Default ของ Rust ค่า id จะเป็น 0, name จะเป็น "" (String ว่าง), และ roleก็จะเป็น "" ... นี่คือการสร้าง "มนุษย์ไร้วิญญาณ" ขึ้นมาในระบบของคุณ User คนนี้ดำรงอยู่ได้โดยไม่มี ID ไม่มีชื่อ ไม่มีบทบาท มันคือขยะ (Garbage Data) ที่ถูกต้องตามกฎของ Type System แต่ผิดต่อกฎของความเป็นจริง

Essentialism สอนให้เราแยกแยะระหว่าง “สิ่งที่ติดตัวมาแต่กำเนิด” กับ “สิ่งที่โลกปรุงแต่งทีหลัง” หากสิ่งใดต้องรอ Input จากภายนอก สิ่งนั้นไม่ใช่แก่นสาร

Option และ None: แก่นสารของความไม่แน่นอน

Rust ออกแบบมาอย่างชาญฉลาดในเรื่องนี้ ลองดูที่ Option<T> แก่นสารของมันคืออะไร? ไม่ใช่ค่า Some ที่ห่อหุ้มข้อมูลมหาศาลไว้ แต่มันคือ None ความว่างเปล่าคือจุดเริ่มต้นของมัน

impl Default for Option<T> คืนค่า None เสมอ... นี่คือสภาวะพื้นฐานที่ปลอดภัยที่สุด มันคือการยอมรับว่า "ในจุดเริ่มต้น ฉันคือความไม่แน่นอน"

เช่นเดียวกับ Vec<T> แก่นสารของมันไม่ใช่ List ที่เต็มไปด้วยข้อมูลหมื่นแถว แต่มันคือ Vec::new() คือพื้นที่ว่างที่พร้อมจะรับข้อมูล การกำหนด Default แบบนี้คือการพา Type นั้นกลับไปที่ "จุดศูนย์" (Zero Point) เพื่อยืนยันว่า ต่อให้ไม่มี Input ใดๆ เลย ฉันก็ยังมีที่ยืนในหน่วยความจำ

สู่การออกแบบที่ชัดเจน

ดังนั้น ครั้งต่อไปที่คุณกำลังออกแบบ Domain Model ใน Rust ขอให้หยุดคิดสักนิด:

  1. อย่าปล่อยให้ Machine กำหนดแก่นสารแทนคุณ: จงหลีกเลี่ยงการใช้ #[derive(Default)] สำหรับ Struct ที่มี Logic ซับซ้อน ถ้าคุณต้องการ Default จง impl Default ด้วยมือของคุณเอง (Manual Implementation)
  2. ถามคำถามสุดท้าย: ก่อนที่คุณจะสั่ง ..Default::default() เพื่อเติมเต็มช่องว่างใน Struct ให้ถามตัวเองว่า "ถ้าโลกนี้ล่มสลายเหลือเพียงค่านี้ ค่านี้ยังนิยามสิ่งที่ฉันสร้างได้อยู่ไหม?" หากคำตอบคือไม่ สิ่งนั้นไม่ควรมี Default
  3. เคารพความบริสุทธิ์: ถ้า Type ของคุณไม่มีสภาวะเริ่มต้นที่สมเหตุสมผล ก็อย่าพยายามสร้างมันขึ้นมา เพียงเพื่อให้โค้ดเขียนง่ายขึ้น มันคือการบิดเบือนแก่นสาร และนั่นคือจุดเริ่มต้นของ Bug ที่แก้ยากที่สุด

ในโลกที่ซับซ้อนและเต็มไปด้วยความผิดพลาด… การมี “แก่นสาร” ที่ชัดเจนและปลอดภัย คือสิ่งเดียวที่ช่วยให้สถาปัตยกรรมของคุณรอดพ้นจากความโกลาหล

ขอให้ 0 ของคุณ คือศูนย์ที่มีความหมาย

เกี่ยวกับผู้เขียน: Uncle Quin — Software Engineer ผู้หลงใหลในการเชื่อมโยงวิศวกรรมซอฟต์แวร์เข้ากับปรัชญา


หากบทความนี้มีประโยชน์

คุณสามารถติดตาม Late Night with Uncle Quin ได้ทาง

ที่ที่เราคุยกันเรื่อง software, engineering mindset และอนาคตของ developer

แบบไม่ต้องใส่สูท

แต่ใส่ความจริงของวงการเข้าไปเต็ม ๆ

Read more

เร็วแค่ไหนก็ไร้ค่า ถ้าไปผิดทาง

เร็วแค่ไหนก็ไร้ค่า ถ้าไปผิดทาง

อีกบทเรียนที่ผมได้จากหนังสือ Slack: Getting Past Burnout, Busywork, and the Myth of Total Efficiency ของ Tom DeMarco คือ ทำไมองค์กรใหญ่ ๆ ถึงยึดมั่นกับ Efficiency กันนัก Efficiency คืออะไร? Efficiency แปลว่า "ประสิทธิภาพ" ยกตัวอย่างเช่น

By Chokchai Phatharamalai
กฎของจั๊วะ

กฎของจั๊วะ

ปีนี้ที่อายุ 44 ผม Reflect ตัวเอง และพบว่าหลักการใช้ชีวิตของผมได้มาจากหนังสือ The Seven Habits of Highly Effective People เยอะมาก ใน Habit ทั้ง 7 นี้จะมีเกร็ดเล็กเกร็ดน้อยที่ผมไปศึกษามา แล้วค่อย ๆ เติมเข้าไปเพื่อทำให้ Habit นั

By Chokchai Phatharamalai
วงจรชีวิตในมุมมอง Existentialism และศิลปะแห่งการล้มเหลวในราคาถูก

วงจรชีวิตในมุมมอง Existentialism และศิลปะแห่งการล้มเหลวในราคาถูก

บ่อยครั้งที่เราใช้ชีวิตราวกับกำลังรอคอยที่จะคอมไพล์ (Compile) โปรเจกต์ยักษ์ใหญ่ที่ซับซ้อนและรวมศูนย์เพียงชิ้นเดียว เราวางแผนสำหรับทศวรรษหน้าอย่างพิถีพิถัน เรายึดโยงความสุขไว้กับจุดหมายปลายทางอันไกลโพ้นและเลือนลางของความสำเร็จสูงสุด เราเขียนโค้ดทางความคิดไว้หลายพันบรรทั

By Santi
วนเวียนแต่ไม่วนลูป: เมื่อชีวิตคือฟังก์ชัน Recursion และการเดินทางสู่พื้นที่ปลอดภัย

วนเวียนแต่ไม่วนลูป: เมื่อชีวิตคือฟังก์ชัน Recursion และการเดินทางสู่พื้นที่ปลอดภัย

ในโลกที่หมุนไปด้วยอัตราเร่งอย่างทุกวันนี้ หลายครั้งเรามักพบว่าตัวเองติดอยู่ท่ามกลางความสับสนยุ่งเหยิง ปัญหาบางอย่างในชีวิตไม่ได้มาในรูปแบบที่เรียบง่าย แต่กลับซ้อนทับกันเป็นชั้น ๆ เหมือนกล่องของขวัญใบยักษ์ที่พอเปิดเข้าไป ก็

By Santi