Lesson 21 of 50 · rust
Traits
Duration: 15 minutes
Lesson 21 of 50 · rust
Duration: 15 minutes
rust\ntrait Drawable {\n fn draw(&self);\n}\n\ntrait Area {\n fn area(&self) -> f64;\n}\n\n\nTrait methods have signatures but no implementations (in the trait definition).\n\n## Implementing Traits\n\nrust\nstruct Circle {\n radius: f64,\n}\n\nimpl Drawable for Circle {\n fn draw(&self) {\n println!(\"Drawing circle with radius {}\", self.radius);\n }\n}\n\nimpl Area for Circle {\n fn area(&self) -> f64 {\n std::f64::consts::PI * self.radius * self.radius\n }\n}\n\nfn main() {\n let circle = Circle { radius: 5.0 };\n circle.draw();\n println!(\"Area: {}\", circle.area());\n}\n\n\n## Default Implementations\n\nTraits can provide default behavior:\n\nrust\ntrait Sound {\n fn make_sound(&self) {\n println!(\"Generic sound\");\n }\n}\n\nstruct Dog;\nimpl Sound for Dog {\n fn make_sound(&self) {\n println!(\"Woof!\"); // Override\n }\n}\n\nstruct Rock;\nimpl Sound for Rock {} // Use default\n\nfn main() {\n Dog.make_sound(); // Woof!\n Rock.make_sound(); // Generic sound\n}\n\n\n## Trait Objects\n\nUse traits for dynamic dispatch:\n\nrust\ntrait Animal {\n fn speak(&self);\n}\n\nstruct Dog;\nimpl Animal for Dog {\n fn speak(&self) { println!(\"Woof!\"); }\n}\n\nstruct Cat;\nimpl Animal for Cat {\n fn speak(&self) { println!(\"Meow!\"); }\n}\n\nfn main() {\n let animals: Vec<Box<dyn Animal>> = vec![\n Box::new(Dog),\n Box::new(Cat),\n ];\n \n for animal in animals {\n animal.speak();\n }\n}\n\n\nThe dyn keyword indicates dynamic dispatch (slower but flexible).\n\n## Trait Bounds\n\nGeneric functions can require types to implement traits:\n\nrust\nfn print_it<T: std::fmt::Display>(val: T) {\n println!(\"Value: {}\", val);\n}\n\nfn main() {\n print_it(42);\n print_it(\"hello\");\n // print_it(vec![1,2]); // ERROR: Vec doesn't implement Display\n}\n\n\n## Multiple Trait Bounds\n\nrust\nfn print_and_compare<T: std::fmt::Display + PartialOrd>(a: T, b: T) {\n if a > b {\n println!(\"a is greater: {}\", a);\n } else {\n println!(\"b is greater: {}\", b);\n }\n}\n\n\n## Trait Bounds with Where Clause\n\nFor complex bounds, use where:\n\nrust\nfn compare<T, U>(a: T, b: U) -> bool\nwhere\n T: std::fmt::Display + PartialOrd<U>,\n U: std::fmt::Display,\n{\n a > b\n}\n\n\n## Implementing Standard Traits\n\nrust\n#[derive(Debug, Clone, Copy, PartialEq)]\nstruct Point {\n x: i32,\n y: i32,\n}\n\n// ou implement manually\nimpl PartialOrd for Point {\n fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {\n let self_dist = self.x * self.x + self.y * self.y;\n let other_dist = other.x * other.x + other.y * other.y;\n self_dist.partial_cmp(&other_dist)\n }\n}\n\n\n## Common Traits\n\n- Clone: Duplicate values\n- Copy: Implicit copying\n- Debug: Debug formatting\n- Display: User-friendly formatting\n- PartialEq, Eq: Equality\n- PartialOrd, Ord: Ordering\n- From, Into: Type conversion\n- Iterator: Iteration support