Last active
May 1, 2024 06:19
-
-
Save mitchmindtree/29d3753fcec4112439ba to your computer and use it in GitHub Desktop.
The ability for derived traits to override their parent trait methods.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Firstly - I LOVE Rust! This is just something that has | |
// been cropping up more and more in my Rust coding experience | |
// recently, so I though it could be good to discuss it with | |
// fellow Rustaceans! | |
// | |
// TOPIC: | |
// I'd love the ability to be able to override parent trait | |
// methods with default methods in the child trait. | |
// | |
// The following is a pattern that I come across very often: | |
trait Foo { | |
fn create_a_thing(&self) -> Thing { ... } | |
fn another_really_handy_method(&self); | |
} | |
trait Bar: Foo { | |
fn create_a_thing(&self) -> Thing { ... but uniquely } // this is what I'd love to be able to do! (See below for a better syntax suggestion) | |
} | |
struct A {..}; impl Foo for A {} | |
struct B {..}; impl Foo for B {} | |
struct C {..}; impl Foo for C {} | |
struct D {..}; impl Bar for D {} | |
struct E {..}; impl Bar for E {} | |
struct F {..}; impl Bar for F {} | |
fn create_all_the_things<T: Foo>(creators: &Vec<Box<T>>) { | |
for creator in creators.iter() { | |
println!("{}", creator.create_a_thing()); // Here, `create_a_thing` would get called uniquely for those that implement Bar if overriding were possible. | |
} | |
} | |
fn main() { | |
let a = box A{..}; | |
let b = box B{..}; | |
let c = box C{..}; | |
let d = box D{..}; | |
let e = box E{..}; | |
let f = box F{..}; | |
let creators = vec!(a, b, c, d, e, f); | |
create_all_the_things(&creators); | |
} | |
// My real case scenarios have many, many more than just 6 types, | |
// but hopefully you can see what I mean (and how this might be | |
// useful) with this small example. | |
// SYNTAX: | |
// Perhaps an explicit syntax could be used to make overriding | |
// parent trait methods both possible, and easy to keep track of: | |
trait Foo { | |
fn create_a_thing(&self) -> Thing { ... } | |
} | |
trait Bar: Foo { | |
over<Foo> fn create_a_thing(&self) -> Thing { ... but uniquely } // `over<Trait>` tells us exactly what trait owns the method that we're overriding. | |
} | |
// Maybe we could be even MORE specific (and help the | |
// compiler out) by requiring explicit syntax upon Foo's | |
// version of the method as well?: | |
trait Foo { | |
virtual fn create_a_thing(&self) -> Thing { ... } // `virtual` indicates the ability for the method to be overridden. | |
} | |
trait Bar: Foo { | |
over<Foo> fn create_a_thing(&self) -> Thing { ... but uniquely } // The overridden version | |
} | |
// MODULE PROBLEM: | |
// "But what if you're using a `MyType` that has implmented | |
// `Bar`, but only `Foo` is imported into the module?" | |
// | |
// POSSIBLE SOLUTION: | |
// Then the compiler should produce an error stating | |
// that "MyType's implementation of Foo's "create_a_thing" | |
// method has been overridden - import the overriding trait | |
// to fix this." | |
// These are my humble thoughts. What are your thoughts? | |
// I realise that Rust draws quite a lot more inspiration | |
// from the FP paradigm, but I feel this could help a lot for | |
// those who are coming from slightly more of an OOP background. | |
// It's a pattern that crops up quite often in OOP, but with the | |
// right explicitness, I feel that Rust could do it better than | |
// it has ever been done before! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
i see!
i asked because i just had a case where i was also wondering if my oop tendencies are playing nice with rust's fp features. what happened was i'm trying to build my own single-window manager from scratch (for one reason or another) and i ended up creating a window trait which then specific window structs are created from.