Traits & Generics

Define shared behavior with traits and write polymorphic code with generics.

Trait Definitions

Traits define a set of methods that types can implement:

trait Display {
    fn to_string(self) -> str
}

trait Area {
    fn area(self) -> f64
}

Implementing Traits

struct Circle {
    radius: f64,
}

impl Area for Circle {
    fn area(self) -> f64 {
        3.14159 * self.radius * self.radius
    }
}

impl Display for Circle {
    fn to_string(self) -> str {
        "Circle"
    }
}

fn main() {
    let c = Circle { radius: 5.0 }
    print(c.area())          // 78.53975
    print(c.to_string())    // Circle
}

Default Methods

Traits can provide default implementations:

trait Describable {
    fn name(self) -> str
    fn describe(self) -> str {
        "I am a " + self.name()
    }
}

Generic Functions

Use type parameters to write functions that work with any type:

fn identity<T>(x: T) -> T { x }

fn main() {
    print(identity(42))        // 42
    print(identity("hello"))   // hello
    print(identity(true))      // true
}

Generic Structs

struct Pair<A, B> {
    first: A,
    second: B,
}

struct Point<T> {
    x: T,
    y: T,
}

type Option<T> {
    Some(T)
    None
}

Trait Bounds

Constrain type parameters to types that implement specific traits:

fn print_area<T: Area>(shape: T) {
    print(shape.area())
}

fn describe<T: Display>(item: T) -> str {
    item.to_string()
}

Built-in Derive Traits

TraitEffectUsage
EqEnables == and != comparisona == b
CloneEnables clone() functionclone(a)
DisplayEnables print() and to_string()print(a)