Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Traits as a return value from a function [duplicate]

Tags:

rust

traits

I have two enums, NormalColour and BoldColour, both of which implement the Colour trait. They contain Blue, BoldGreen, and so on.

I'd like to return values of both of these types from the same function, treating them as though they're just a Colour value, calling the paint function on the result, but I can't find a way to coerce the Rust complier into doing this for me. I'd like to be able to write something like this:

pub trait Colour {
    fn paint(&self, input: &str) -> String;
}

fn file_colour(stat: &io::FileStat) -> Colour {
    if stat.kind == io::TypeDirectory {
        Blue
    } else if stat.perm & io::UserExecute == io::UserExecute {
        BoldGreen
    } else {
        White
    }
}

What type do I have to make the function return for it to work?

I'll eventually like to make more types implement Colour, which is why I'm not interested in just turning the two enums into one big enum.

like image 725
Ben S Avatar asked May 02 '14 21:05

Ben S


1 Answers

The answer is trait objects. This means that you will work with Box<Colour> as your type; bare Colour is not an instantiable type. You can cast Box<T> objects to Box<Colour> with the as operator: Box::new(NormalColour::White) as Box<Colour>. In many places this is not necessary (just write Box::new(NormalColour::White) and it can be automatically coerced to Box<Colour>), but sometimes it will still be necessary.

Still, if you can do it as an enum, that will probably be a nicer solution.

like image 67
Chris Morgan Avatar answered Feb 22 '23 05:02

Chris Morgan