Module 7 • Lesson 39

Common Standard Traits

📚 10 min💻 Free🦀 nixus.pro

Common Standard Traits

use std::fmt;
use std::ops::{Add, Mul, Neg};

#[derive(Debug, Clone, Copy, PartialEq)]
struct Vec2 { x: f64, y: f64 }

impl Vec2 {
    fn new(x: f64, y: f64) -> Self { Vec2 { x, y } }
    fn length(&self) -> f64 { (self.x*self.x + self.y*self.y).sqrt() }
}

// Display: human-readable format
impl fmt::Display for Vec2 {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({:.2}, {:.2})", self.x, self.y)
    }
}

// Add operator overloading
impl Add for Vec2 {
    type Output = Vec2;
    fn add(self, other: Vec2) -> Vec2 {
        Vec2::new(self.x + other.x, self.y + other.y)
    }
}

// Mul by scalar
impl Mul for Vec2 {
    type Output = Vec2;
    fn mul(self, scalar: f64) -> Vec2 {
        Vec2::new(self.x * scalar, self.y * scalar)
    }
}

// Neg: unary minus
impl Neg for Vec2 {
    type Output = Vec2;
    fn neg(self) -> Vec2 { Vec2::new(-self.x, -self.y) }
}

// Default: zero value
impl Default for Vec2 {
    fn default() -> Self { Vec2::new(0.0, 0.0) }
}

fn main() {
    let a = Vec2::new(1.0, 2.0);
    let b = Vec2::new(3.0, 4.0);
    println!("{}", a + b);      // (4.00, 6.00)
    println!("{}", a * 2.0);    // (2.00, 4.00)
    println!("{}", -a);          // (-1.00, -2.00)
    println!("{}", Vec2::default()); // (0.00, 0.00)
    println!("{}", a == a);     // true
}

Iterator Implementation

struct Counter { count: u32, max: u32 }

impl Counter {
    fn new(max: u32) -> Self { Counter { count: 0, max } }
}

impl Iterator for Counter {
    type Item = u32;
    fn next(&mut self) -> Option {
        if self.count < self.max {
            self.count += 1;
            Some(self.count)
        } else { None }
    }
}

fn main() {
    // Custom iterator works with ALL iterator adapters!
    let sum: u32 = Counter::new(5).sum();
    let evens: Vec = Counter::new(10).filter(|x| x % 2 == 0).collect();
    println!("sum={} evens={:?}", sum, evens);
}

🎯 Practice

  1. Implement Add, Sub, Mul for a Matrix2x2 struct
  2. Implement Iterator for a Fibonacci struct that yields Fibonacci numbers
  3. Implement From<(f64, f64)> for Vec2 to allow Vec2::from((1.0, 2.0))

🎉 Key Takeaways