You're already familiar with implementing traits in Rust, let's explore some special traits from the standard library - specifically those that allow operator overloading through the std::ops
module.
One such trait is Add
, which allows you to implement custom behavior for the +
operator. This is particularly useful when working with types that have a natural addition operation, like measurements or mathematical types.
Let's implement custom addition between different units of measurement. You'll create a system where you can add meters to millimeters, with automatic unit conversion.
Your job is to implement a Millimeters
struct and a Meters
struct, then implement the Add
trait to allow adding a Meters
value to a Millimeters
value. The result should be a new Millimeters
value.
Millimeters
and Meters
, each holding a single u32
valueAdd<Meters>
trait for Millimeters
to handle addition with Meters
Millimeters
If you're stuck, here are some hints to help you solve the challenge!
The Add
trait requires you to specify:
type Output = Millimeters;
fn add(self, other: Meters) -> Self::Output;
Remember that meters must be multiplied by 1000
to convert to millimeters
Access tuple struct fields with .0
use std::ops::Add;pub struct Millimeters(pub u32);pub struct Meters(pub u32);// Implement the Add<Meters> trait for Millimetersimpl Add<Meters> for Millimeters { type Output = Millimeters; fn add(self, rhs: Meters) -> Self::Output { Millimeters(self.0 + rhs.0 * 1000) }}// Example usagepub fn main() { let length1 = Millimeters(1500); let length2 = Meters(3); let result = length1 + length2; assert_eq!(result.0, 4500, "Expected 1500mm + 3000mm to equal 4500mm"); println!("Result: {}mm", result.0);}
use std::ops::Add;pub struct Millimeters(pub u32);pub struct Meters(pub u32);// Implement the Add traitimpl Add<Meters> for Millimeters { type Output = Millimeters; fn add(self, rhs: Meters) -> Self::Output { Millimeters(self.0 + rhs.0 * 1000) }}// Example usagepub fn main() { let length1 = Millimeters(1500); let length2 = Meters(3); let result = length1 + length2; assert_eq!(result.0, 4500, "Expected 1500mm + 3000mm to equal 4500mm");}
use std::ops::Add;pub struct Millimeters(pub u32);pub struct Meters(pub u32);// Implement the Add traitimpl Add<Meters> for Millimeters { type Output = Millimeters; fn add(self, rhs: Meters) -> Self::Output { let converted = rhs.0 * 1000; Self(converted + self.0) }}// Example usagepub fn main() { let length1 = Millimeters(1500); let length2 = Meters(3); let result = length1 + length2; assert_eq!(result.0, 4500, "Expected 1500mm + 3000mm to equal 4500mm");}
pub struct Millimeters(pub u32);pub struct Meters(pub u32);// Implement the Add traitimpl std::ops::Add<Meters> for Millimeters { type Output = Millimeters; fn add(self, rhs: Meters) -> Self::Output { Millimeters(self.0 + rhs.0 * 1000) }}// Example usagepub fn main() { let length1 = Millimeters(1500); let length2 = Meters(3); let result = length1 + length2; assert_eq!(result.0, 4500, "Expected 1500mm + 3000mm to equal 4500mm");}
use std::ops::Add;pub struct Millimeters(pub u32);pub struct Meters(pub u32);// Implement the Add traitimpl Add<Meters> for Millimeters { type Output = Millimeters; fn add(self, other: Meters) -> Millimeters { let mm = self.0 + other.0 * 1000; Millimeters(mm) }}// Example usagepub fn main() { let length1 = Millimeters(1500); let length2 = Meters(3); let result = length1 + length2; assert_eq!(result.0, 4500, "Expected 1500mm + 3000mm to equal 4500mm");}
pub struct Millimeters(pub u32);pub struct Meters(pub u32);// Implement the Add traitimpl std::ops::Add<Meters> for Millimeters { type Output = Self; fn add(self, other: Meters) -> Self::Output { Self(other.0 * 1000 + self.0) }}// Example usagepub fn main() { let length1 = Millimeters(1500); let length2 = Meters(3); let result = length1 + length2; assert_eq!(result.0, 4500, "Expected 1500mm + 3000mm to equal 4500mm");}
pub struct Millimeters(pub u32);pub struct Meters(pub u32);// Implement the Add traitimpl std::ops::Add<Meters> for Millimeters { type Output = Self; fn add(self, other: Meters) -> Self::Output { Self(self.0 + other.0 * 1000) }}// Example usagepub fn main() { let length1 = Millimeters(1500); let length2 = Meters(3); let result = length1 + length2; assert_eq!(result.0, 4500, "Expected 1500mm + 3000mm to equal 4500mm");}
use std::ops::{Add};pub struct Millimeters(pub u32);pub struct Meters(pub u32);// Implement the Add traitimpl Add<Meters> for Millimeters { type Output = Millimeters; fn add(self, rhs: Meters) -> Self::Output { Millimeters(self.0 + rhs.0 * 1000) }}// Example usagepub fn main() { let length1 = Millimeters(1500); let length2 = Meters(3); let result = length1 + length2; assert_eq!(result.0, 4500, "Expected 1500mm + 3000mm to equal 4500mm");}
pub struct Millimeters(pub u32);pub struct Meters(pub u32);use std::ops::Add;// Implement the Add traitimpl Add<Meters> for Millimeters { type Output = Millimeters; fn add(self, other: Meters) -> Self::Output { Millimeters(self.0 + 1000 * other.0) }}// Example usagepub fn main() { let length1 = Millimeters(1500); let length2 = Meters(3); let result = length1 + length2; assert_eq!(result.0, 4500, "Expected 1500mm + 3000mm to equal 4500mm");}
pub struct Millimeters(pub u32);pub struct Meters(pub u32);// Implement the Add traitimpl std::ops::Add<Meters> for Millimeters { type Output = Self; fn add(self, other: Meters) -> Self::Output { Self(self.0 + 1000 * other.0) }}// Example usagepub fn main() { let length1 = Millimeters(1500); let length2 = Meters(3); let result = length1 + length2; assert_eq!(result.0, 4500, "Expected 1500mm + 3000mm to equal 4500mm");}
use std::ops::Add;pub struct Millimeters(pub u32);pub struct Meters(pub u32);// Implement the Add traitimpl Add<Meters> for Millimeters { type Output = Millimeters; fn add(self, other: Meters) -> Millimeters { Millimeters(self.0 + (other.0 * 1000)) }}// Example usagepub fn main() { let length1 = Millimeters(1500); let length2 = Meters(3); let result = length1 + length2; assert_eq!(result.0, 4500, "Expected 1500mm + 3000mm to equal 4500mm");}
use std::ops::Add;pub struct Millimeters(pub u32);pub struct Meters(pub u32);// Implement the Add traitimpl Add<Meters> for Millimeters { type Output = Millimeters; fn add(self, rhs: Meters) -> Self::Output { Millimeters(self.0 + rhs.0 * 1000) }}// Example usagepub fn main() { let length1 = Millimeters(1500); let length2 = Meters(3); let result = length1 + length2; assert_eq!(result.0, 4500, "Expected 1500mm + 3000mm to equal 4500mm");}
pub struct Millimeters(pub u32);pub struct Meters(pub u32);// Implement the Add traitimpl std::ops::Add<Meters> for Millimeters{ type Output = Millimeters; fn add(self, op2: Meters)-> Self::Output{ Millimeters(self.0+op2.0*1000) }}// Example usagepub fn main() { let length1 = Millimeters(1500); let length2 = Meters(3); let result = length1 + length2; assert_eq!(result.0, 4500, "Expected 1500mm + 3000mm to equal 4500mm");}
pub struct Millimeters(pub u32);pub struct Meters(pub u32);// Implement the Add traitimpl std::ops::Add<Meters> for Millimeters { type Output = Millimeters; fn add(self, others: Meters) -> Self::Output { Millimeters(others.0 * 1000 + self.0) }}
pub struct Millimeters(pub u32);pub struct Meters(pub u32);// Implement the Add traitimpl std::ops::Add<Meters> for Millimeters { type Output = Millimeters; fn add(self, other: Meters) -> Self::Output { Millimeters(self.0 + (other.0 * 1000)) }}// Example usagepub fn main() { let length1 = Millimeters(1500); let length2 = Meters(3); let result = length1 + length2; assert_eq!(result.0, 4500, "Expected 1500mm + 3000mm to equal 4500mm");}
pub struct Millimeters(pub u32);pub struct Meters(pub u32);// Implement the Add traitimpl std::ops::Add<Meters> for Millimeters { type Output = Self; fn add(self, other: Meters) -> Self::Output { Millimeters(self.0 + other.0 * 1000) }}// Example usagepub fn main() { let length1 = Millimeters(1500); let length2 = Meters(3); let result = length1 + length2; assert_eq!(result.0, 4500, "Expected 1500mm + 3000mm to equal 4500mm");}
use std::ops::Add;pub struct Millimeters(pub u32);pub struct Meters(pub u32);impl Add<Meters> for Millimeters { type Output = Self; fn add(self, meters: Meters) -> Millimeters { Millimeters(self.0 + meters.0 * 1000) }}// Example usagepub fn main() { let length1 = Millimeters(1500); let length2 = Meters(3); let result = length1 + length2; assert_eq!(result.0, 4500, "Expected 1500mm + 3000mm to equal 4500mm");}
use std::ops::Add;pub struct Millimeters(pub u32);pub struct Meters(pub u32);// Implement the Add traitimpl Add<Meters> for Millimeters { type Output = Self; fn add(self, meters: Meters) -> Millimeters { Millimeters(self.0 + meters.0 * 1000) }}// Example usagepub fn main() { let length1 = Millimeters(1500); let length2 = Meters(3); let result = length1 + length2; assert_eq!(result.0, 4500, "Expected 1500mm + 3000mm to equal 4500mm");}
use std::ops;pub struct Millimeters(pub u32);pub struct Meters(pub u32);// Implement the Add traitimpl ops::Add<Meters> for Millimeters { type Output = Millimeters; fn add(self, other: Meters) -> Self::Output { Self(self.0 + other.0 * 1000) }}// Example usagepub fn main() { let length1 = Millimeters(1500); let length2 = Meters(3); let result = length1 + length2; assert_eq!(result.0, 4500, "Expected 1500mm + 3000mm to equal 4500mm");}
use std::ops::Add;pub struct Millimeters(pub u32);pub struct Meters(pub u32);impl Add<Meters> for Millimeters { type Output = Millimeters; fn add(self, rhs: Meters) -> Millimeters { let n = self.0 + (rhs.0 * 1000); Millimeters(n) }}// Example usagepub fn main() { let length1 = Millimeters(1500); let length2 = Meters(3); let result = length1 + length2; assert_eq!(result.0, 4500, "Expected 1500mm + 3000mm to equal 4500mm");}
use std::ops::Add;pub struct Millimeters(pub u32);pub struct Meters(pub u32);// Implement the Add traitimpl Add<Meters> for Millimeters { type Output = Millimeters; fn add(self, rhs: Meters) -> Self::Output { Self(self.0 + rhs.0 * 1000) }}// Example usagepub fn main() { let length1 = Millimeters(1500); let length2 = Meters(3); let result = length1 + length2; assert_eq!(result.0, 4500, "Expected 1500mm + 3000mm to equal 4500mm");}
use std::ops::Add;pub struct Millimeters(pub u32);pub struct Meters(pub u32);impl Add<Meters> for Millimeters { type Output = Millimeters; fn add(self, other: Meters) -> Self::Output { Millimeters(self.0 + other.0 * 1000) }}// Example usagepub fn main() { let length1 = Millimeters(1500); let length2 = Meters(3); let result = length1 + length2; assert_eq!(result.0, 4500, "Expected 1500mm + 3000mm to equal 4500mm");}
pub struct Millimeters(pub u32);pub struct Meters(pub u32);// Implement the Add traitimpl std::ops::Add<Meters> for Millimeters { type Output = Millimeters; fn add(self, rhs: Meters) -> Self::Output { Millimeters(self.0 + 1000 * rhs.0) }}// Example usagepub fn main() { let length1 = Millimeters(1500); let length2 = Meters(3); let result = length1 + length2; assert_eq!(result.0, 4500, "Expected 1500mm + 3000mm to equal 4500mm");}
use std::ops::{Add};pub struct Millimeters(pub u32);pub struct Meters(pub u32);// Implement the Add traitimpl Add<Meters> for Millimeters { type Output = Self; fn add(self, rhs: Meters) -> Self::Output { Self(rhs.0 * 1000 + self.0) }}// Example usagepub fn main() { let length1 = Millimeters(1500); let length2 = Meters(3); let result = length1 + length2; assert_eq!(result.0, 4500, "Expected 1500mm + 3000mm to equal 4500mm");}