top | item 43923785

(no title)

esailija | 9 months ago

The problem is of course that there is no useful default behavior you can define when the trait is so isolated and generic.

discuss

order

josephg|9 months ago

It doesn't have to be "so isolated". The trait can still have required methods that don't have a default implementation. Eg:

    trait Robot {
        fn send_command(&mut self, command: Command);

        fn stop(&mut self) {
            self.send_command(Command.STOP);
        }
    }

    struct BenderRobot;
    
    impl Robot for BenderRobot {
        // Required.
        fn send_command(&mut self, command: Command) { todo!(); } 
    }
This is starting to look a lot like C++ class inheritance. Especially because traits can also inherit from one another. However, there are two important differences: First, traits don't define any fields. And second, BenderRobot is free to implement lots of other traits if it wants, too.

If you want a real world example of this, take a look at std::io::Write[1]. The write trait requires implementors to define 2 methods (write(data) and flush()). It then has default implementations of a bunch more methods, using write and flush. For example, write_all(). Implementers can use the default implementations, or override them as needed.

Docs: https://doc.rust-lang.org/std/io/trait.Write.html

Source: https://doc.rust-lang.org/src/std/io/mod.rs.html#1596-1935

RHSeeger|9 months ago

> First, traits don't define any fields.

How does one handle cases where fields are useful? For example, imagine you have a functionality to go fetch a value and then cache it so that future calls to get that functionality are not required (resource heavy, etc).

    // in Java because it's easier for me
    public interface hasMetadata {
        Metadata getMetadata() {
            // this doesn't work because interfaces don't have fields
            if (this.cachedMetadata == null) {
                this.cachedMetadata = generateMetadata();
            }
            return this.cachedMetadata;
        }
        // relies on implementing class to provide
        Metadata fetchMetadata(); 

    }

jjmarr|9 months ago

Don't mix implementation and interface inheritance.