this post was submitted on 02 Jul 2021
13 points (100.0% liked)

Rust Programming

8335 readers
2 users here now

founded 5 years ago
MODERATORS
 

Here is a simplified example of my problem:

struct User;
struct Community;

enum Actor {
    User(User),
    Community(Community),
}

trait Name {
    fn name() -> &'static str;
}

impl Name for User {
    fn name() -> &'static str { "/u/nutomic" }
}

impl Name for Community {
    fn name() -> &'static str { "/c/rust " }
}

fn main() {
    let actor = Actor::Community(Community);
    println!("{}", actor.name());
}

Playground link

As you may have noticed, this doesnt compile. The only solution I can think of is with a match. I want to avoid that because I have an enum with 30+ variants, and a trait with multiple methods. So that would be a huge match statement in each method, when the compiler should know that the enum variants all have the same trait.

So, do you know any way to make this work without match?

you are viewing a single comment's thread
view the rest of the comments
[–] [email protected] 2 points 3 years ago (1 children)

Just implement Name for Actor.

[–] [email protected] 1 points 3 years ago (1 children)

That requires using a match statement in the implementation, though, does it not?

[–] [email protected] 1 points 3 years ago (1 children)

Yes, match is how you access enum variants in Rust. You only need to implement it once for the Actor enum.

[–] [email protected] 1 points 3 years ago (2 children)

Yeah, but the question was about not having to use such a match statement or somehow making it less verbose, since they have 30 enum variants and several methods in that trait, so the file that implements the trait would become very long.

[–] [email protected] 2 points 3 years ago

In this case you may want to use a trait object instead of an enum.

[–] [email protected] 2 points 3 years ago

The only way to destructure an enum is via match or if let statements. If all enum variants would contain common data then I would suggest to move this data to a struct and keep the enum as separate field in that structure (same like io::Error and it's Kind enumeration). Another way would be to use a macro to derive the implementation automatically; there may be crates already there that can do this sort of delegation. See https://crates.io/search?q=delegate

Enum variants are values and not types. You cannot implement traits for values. Rust will not magically implement traits for you (unless they are auto-traits, and this currently are not user defined). Rust does not support inheritance (it is not an OOP language) and instead you use composition which means that you have to compose things manually (or via macro) if you use static constructs like the enum (in contrast to run-time trait object).