Skip to content

Comment on Rust Any part 3: we have upcastsparent

Comments

It’s not clear from that description how it differs from interface inheritance in OOP.

In an interface/class hierarchy A < B < C, C can be an abstract class that only implements B’s methods and not A’s.

In Rust, an implementation of a trait never implements methods that weren't defined on that trait explicitly. In your example, an implementation of C inherits from B and A, but only implements B's methods. In Rust, an implementation of C cannot itself implement B's or A's methods; it is merely allowed to assume that they have been implemented elsewhere. This also means that subtraits cannot override the behavior of methods defined on supertraits.

Okay, but doesn't Bar nevertheless inherit Foo's methods in the sense of interface inheritance? Or does code that gets passed a Bar not get access to Foo's methods?

does code that gets passed a Bar not get access to Foo's methods

Prior to the current version of Rust it was impossible to access methods on `Foo` when a `&dyn Bar` was passed. With the current beta version you can upcast.

Prior to the current version of Rust it was impossible to access methods on `Foo` when a `&dyn Bar` was passed.

This has been working since Rust 1.0, I think:

    trait Foo {
        fn foo(&self);
    }
    trait Bar : Foo {}

    impl Foo for () {
        fn foo(&self) { println!("Hello") }
    }
    impl Bar for () {}

    fn xxx(x: &dyn Bar) {
       x.foo();
    }

    pub fn main() {
        xxx(&());
    }
> With the current beta version you can upcast

Right. Now you can convert from `&dyn Bar` to `&dyn Foo` which wasn't possible before.

Inherent method implementations were unavailable. (Eg: impl dyn Foo) and then call this via Bar.

It might be better to think of it this way: types in Rust do not implement traits, traits are implemented for types. It might seem subtle, but its not: a trait can be implemented for a type without that type's knowledge (obviously taking care for the orphan rule). Traits are also implemented via pattern matching (Into being implemented for all Froms is the most trivial example). Go's interfaces come closer to Rust traits than those from OOP languages.

I've experienced a lot of fear in other people, especially when interviewing, about Rust not being OOP. Very smart people seem to be coming up with carve-outs to keep that religion alive. Try letting go of OOP for a month or two, and you'll find that you're better off letting OOP be someone else's problem.

I think we have different notions of OOP. OOP without implementation inheritance and with extension interfaces/methods is still very much OOP to me.

It’s not clear from that description how it differs from interface inheritance in OOP.

Remember, when people talk about "OOP" what they're actually talking about is Java EE 6.

AboutSource Built by g1lg1l

Hackerly is an independent reader for Hacker News, built on the public HN API. Not affiliated with Y Combinator.