สรุป The Rust Programming Language ฉบับมือเก่า ตอนที่ 10.1
บทความนี้สรุปจากหนังสือ The Rust Programming Language chapter 10.1 ด้วยความคิดเห็นของผมเอง อาจมีการตีความที่มีโอกาสผิดพลาดได้ ทางที่ดีถ้าอยากได้ reference จริงๆแนะนำต้นทางครับ
ตอนที่ 10 จะเกี่ยวกับ Generic Types, Traits, and Lifetimes ซึ่งผมคิดว่าน่าจะเป็นเรื่องยาวเลยขอแบ่งเป็น 3 ตอนก็แล้วกันครับ (จริงๆคือขี้เกียจด้วย 55 เพราะ long vacation อยู่)
10.1 Generic Data Types
ตอนต้นของบทที่ 10 จะพยายามอธิบาย inspiration ของ why do we need generic โดยการโยงไปที่การ reduce duplication ซึ่งอธิบายค่อนข้างละเอียดตั้งแต่การ extract function จาก code ที่ทำงานคล้ายๆกัน (แต่ผมคิดว่าส่วนนี้ค่อนข้างจะ skimming ผ่านๆได้)
ต่อมาเค้าก็จะพูดต่อไปถึงการลด code duplication ในระดับ type level ซึ่งก็คือการใช้ generic type
สำหรับใครที่เคยใช้ generic type ในภาษาอื่นๆมาแล้วแทบจะข้ามไปได้เลย จะมีประเด็นแค่เรื่องตอน define พวก associated functions (พวกที่ใช้ impl
) ที่จะ define ด้วย impl<T> Struct_name<T> {}
แล้วสามารถ associate concrete function ได้ด้วยโค้ดแนวๆนี้
impl SomeStruct<f32> {
fn a_func(&self) -> f32 {
// body
}
}
โค้ดด้านบนนี้จะทำให้ method a_func()
available แค่ใน SomeStruct<f32>
เท่านั้น เป็นการใช้ concrete type มาเป็น constraint
นอกจากนั้นก็คล้ายๆภาษาอื่นๆเลย 😅
แต่ถ้าใครยังไม่ค่อยคุ้นกับ generic type ผมก็แนะนำว่าอ่านบทความเต็มๆจะดีกว่า ถ้าให้ผมสรุปตามความเข้าใจของผม มันก็คือการที่เรา create a layer of abstraction on type level แบบเดียวกับที่เราทำกับการ extract function จาก code ที่ทำงานคล้ายๆกันน่ะแหล่ะ แต่อันนี้เป็น type หรือลักษณะของ code ที่คล้ายๆกัน เราไปทำให้ตัว type มันรับ type parameter เป็น concrete type ขึ้นมาได้เท่านั้นเอง
เช่น Option<T>
แบบนี้ทำให้เราไม่จำเป็นต้องมี Option<i32>, Option<char>, Option<any_type>
ลองคิดดูว่าถ้าไม่มี generic type เราก็ต้องมีจำนวน concrete types ที่เยอะแยะเต็มไปหมด
ท้ายบทความเค้ามีพูดถึงเรื่อง performance นิดๆว่ามันไม่กิน runtime perf เนื่องจาก compiler จะแปลงพวก generic types ให้กลายเป็น concrete types ให้ :)
จบแล้วบทที่ 10.1