This question already has an answer here:
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.
The answer is trait objects. This means that you will work with
Box<Colour>
as your type; bareColour
is not an instantiable type. You can castBox<T>
objects toBox<Colour>
with theas
operator:Box::new(NormalColour::White) as Box<Colour>
. In many places this is not necessary (just writeBox::new(NormalColour::White)
and it can be automatically coerced toBox<Colour>
), but sometimes it will still be necessary.Still, if you can do it as an enum, that will probably be a nicer solution.
The answer above suggests:
which works, but you need to wrap all of the returns in a
Box::new()
call.However, in Rust 1.26 you can now say
and simply return the value. No
Box
needed.