นี่คือตัวอย่างโค้ดแบบเต็มที่นำ Dog, Cat, และ Bird มาสร้างและเรียกใช้งานผ่านฟังก์ชัน print_speak(item: &dyn Speaker) ครับ คุณสามารถก๊อปปี้โค้ดนี้ไปรันในโปรเจกต์ Rust หรือใน Rust Playground ได้เลยครับ
// 1. นิยาม Trait ขึ้นมา
trait Speaker {
fn speak(&self);
}
// 2. สร้าง Type (Struct) ทั้ง 3 ตัว
struct Dog;
struct Cat;
struct Bird;
// 3. Implement Trait ให้กับแต่ละ Type
impl Speaker for Dog {
fn speak(&self) {
println!("🐶 โฮ่ง ๆ!");
}
}
impl Speaker for Cat {
fn speak(&self) {
println!("🐱 เหมียว ๆ!");
}
}
impl Speaker for Bird {
fn speak(&self) {
println!("🐦 จิ๊บ ๆ!");
}
}
// 4. ฟังก์ชันที่ใช้ `dyn Trait` (Dynamic Dispatch)
fn print_speak(item: &dyn Speaker) {
// ตอนรันโปรแกรมจะมาเปิดตาราง vtable ที่นี่เพื่อดูว่าต้องเรียกฟังก์ชันของตัวไหน
item.speak();
}
fn main() {
// สร้าง Instance ของสัตว์แต่ละตัว
let my_dog = Dog;
let my_cat = Cat;
let my_bird = Bird;
println!("--- เรียกใช้งานทีละตัวผ่านฟังก์ชัน ---");
// ส่ง Reference (&) เข้าไป ตัวแปรจะถูกแปลงเป็น Fat Pointer อัตโนมัติ
print_speak(&my_dog);
print_speak(&my_cat);
print_speak(&my_bird);
println!("\n--- ประโยชน์ของ dyn: เอามาใส่ Vec รวมกันได้ด้วย ---");
// ด้วยพลังของ `dyn` เราสามารถเอาคนละ Type มาเก็บใน Vec เดียวกันได้ (Heterogeneous Collection)
let zoo: Vec<&dyn Speaker> = vec![&my_dog, &my_cat, &my_bird];
for animal in zoo {
print_speak(animal);
}
}
💡 อธิบายจุดสำคัญในโค้ด