Rust Tutorial · Traits and Generics · Lesson 20 of 29
Rust Traits
Define shared behaviour with traits, implement them for your types, and use default methods.
Defining and implementing traits
A trait describes behaviour that types can implement, similar to interfaces in other languages:
trait Shape {
fn area(&self) -> f64;
fn describe(&self) -> String { // default method
format!("a shape with area {:.1}", self.area())
}
}
struct Circle { radius: f64 }
struct Rect { w: f64, h: f64 }
impl Shape for Circle {
fn area(&self) -> f64 { std::f64::consts::PI * self.radius * self.radius }
}
impl Shape for Rect {
fn area(&self) -> f64 { self.w * self.h }
fn describe(&self) -> String { format!("a {}x{} rectangle", self.w, self.h) }
}
fn main() {
println!("{}", Circle { radius: 1.0 }.describe());
println!("{}", Rect { w: 2.0, h: 3.0 }.describe());
}
Output
a shape with area 3.1 a 2x3 rectangle
Run this on your computer — see “Get Started” for setup.
Standard traits you'll implement
Display (user-facing text), Debug (developer output, usually derived), Clone, PartialEq/Eq,
PartialOrd/Ord, Hash, Default, and From for conversions.
use std::fmt;
#[derive(Debug, Default, Clone, Copy, PartialEq)]
struct Money { cents: i64 }
impl fmt::Display for Money {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "${}.{:02}", self.cents / 100, self.cents % 100)
}
}
impl From<f64> for Money {
fn from(dollars: f64) -> Self { Money { cents: (dollars * 100.0).round() as i64 } }
}
fn main() {
let price: Money = 19.99.into();
println!("{price} / {price:?} / default {}", Money::default());
}
Output
$19.99 / Money { cents: 1999 } / default $0.00Run this on your computer — see “Get Started” for setup.
Test yourself
What is a trait in Rust?
A kind of structA set of methods that types can implement, like an interfaceA macroA module
Show answer
Answer: A set of methods that types can implement, like an interface