Skip to main content
Brave Programmer Logo

BraveProgrammer

BraveProgrammer

HomeProjectsBlogsCoursesLessonsAbout

Site footer

BraveProgrammer

Free coding courses, practical tutorials, and real projects from BraveProgrammer. Learn web development with React, Next.js, and TypeScript.

Navigation

  • Home
  • Projects
  • Blogs
  • Courses

Resources

  • About
  • Lessons

© 2026 BraveProgrammer. All rights reserved.

  1. Courses
  2. /
  3. Rust Fundamentals

Lesson 21 of 50 · rust

Traits

Duration: 15 minutes

Traits\n\nTraits define shared behavior across types, similar to interfaces in other languages. They enable polymorphism and code reuse in Rust.\n\n## Defining Traits\n\nrust\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

Previous: Panic and UnwindingNext: Implementing Traits