Skip to content

Instantly share code, notes, and snippets.

@philsquared
Last active May 5, 2021 10:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save philsquared/81219b0e2cb1f3c2c642ed338f2fa66e to your computer and use it in GitHub Desktop.
Save philsquared/81219b0e2cb1f3c2c642ed338f2fa66e to your computer and use it in GitHub Desktop.
Fitting a SquarePeg into a RoundHole, in Rust
trait Square {
fn size(&self) -> f64;
fn perimeter(&self) -> f64;
}
trait Circle {
fn radius(&self) -> f64;
fn perimeter(&self) -> f64;
}
struct RoundHole;
impl RoundHole {
fn fit( circle_shaped_thing: &impl Circle ) {
println!("Fit with radius: {}", circle_shaped_thing.radius() );
}
}
// Square is defined with no mention of traits
struct SquarePeg {
size: f64
}
// We can add implementations for specific traits later - even to third-party code
// (as long as either the trait or the struct is local)
// Therefore traits are non-intrusive
impl Square for SquarePeg {
fn size(&self) -> f64 {
return self.size;
}
fn perimeter(&self) -> f64 {
return self.size*4.0;
}
}
// --- Don't immediately implement this
impl Circle for SquarePeg {
fn radius(&self) -> f64 {
return (2.0*(self.size/2.0).powf(2.0)).sqrt();
}
fn perimeter(&self) -> f64 {
return 2.0*(std::f64::consts::PI*self.radius());
}
}
// ----
fn main() {
let square_peg = SquarePeg{ size: 42.0 };
println!("size: {}", square_peg.size() );
// doesn't work until Circle implemented for SquarePeg
RoundHole::fit( &square_peg );
// Doesn't work until we add the 'as' casts
println!("perimeter: {}", (&square_peg as &dyn Square).perimeter() );
// Or, more idiomatically (or more cleanly), call the perimeter method explicity from the trait
println!("perimeter: {}", Circle::perimeter(&square_peg ) );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment