Generics
Generic Functions
หัวข้อที่มีชื่อว่า “Generic Functions”ลองนึกภาพว่าคุณต้องหาค่าที่ใหญ่ที่สุดใน slice สำหรับ integer คุณเขียน largest_i32 สำหรับ char คุณเขียน largest_char — body เหมือนกันทุกอย่างแต่ต่าง type Generics แก้ปัญหานี้โดยให้คุณใช้ type parameter แทน concrete type:
fn largest<T: PartialOrd>(list: &[T]) -> &T { // ...}ตัว <T: PartialOrd> อ่านว่า “สำหรับ type ใดก็ตาม T ที่ implement PartialOrd” Trait bound PartialOrd บอก compiler ว่า T รองรับการเปรียบเทียบด้วย >
Generic Structs
หัวข้อที่มีชื่อว่า “Generic Structs”คุณสามารถทำให้ struct เป็น generic ได้เช่นกัน ทำให้ field ทำงานกับ type ใดก็ได้:
struct Pair<T> { first: T, second: T,}Pair<i32> เก็บ integer สองอัน Pair<String> เก็บ String สองอัน เป็นต้น
Trait Bounds บน impl Blocks
หัวข้อที่มีชื่อว่า “Trait Bounds บน impl Blocks”เมื่อคุณต้องการ implement method สำหรับ generic struct ด้วย constraint บางอย่าง:
impl<T: std::fmt::Display + PartialOrd> Pair<T> { fn larger(&self) -> &T { if self.first > self.second { &self.first } else { &self.second } }}T: Display + PartialOrd บอกว่า method larger มีให้เฉพาะ Pair<T> ที่ T รองรับทั้ง formatting และการเปรียบเทียบ
Where Clauses
หัวข้อที่มีชื่อว่า “Where Clauses”เมื่อ trait bound ยาวหรือซับซ้อน คุณสามารถย้ายไปไว้ใน where clause เพื่อให้อ่านง่ายขึ้น:
fn notify<T>(item: &T)where T: std::fmt::Display + Clone,{ println!("{}", item);}ทั้งสอง syntax ทำงานเหมือนกันทุกประการ — where เป็นแค่ทางเลือกที่อ่านง่ายกว่าสำหรับ bound ที่ซับซ้อน
ลองเล่น
หัวข้อที่มีชื่อว่า “ลองเล่น”Playground ด้านล่างแสดง largest function แบบ generic, struct Pair<T> และ method ที่มี compound trait bound
fn largest<T: PartialOrd>(list: &[T]) -> &T { let mut biggest = &list[0]; for item in list { if item > biggest { biggest = item; } } biggest}
struct Pair<T> { first: T, second: T,}
impl<T: std::fmt::Display + PartialOrd> Pair<T> { fn new(first: T, second: T) -> Self { Self { first, second } }
fn larger(&self) -> &T { if self.first > self.second { &self.first } else { &self.second } }}
fn main() { let numbers = vec![34, 50, 25, 100, 65]; println!("largest number: {}", largest(&numbers));
let chars = vec!['y', 'm', 'a', 'q']; println!("largest char: {}", largest(&chars));
let p = Pair::new(5, 10); println!("larger of pair: {}", p.larger());}Compiling…