Enum field expressions?


#1

I’ve been trying to find this in the documentation, but without success. Is there any way to enable field access to an enum? Specifically, I’d love to be able to access fields with field expressions when the same named field (with the same type) is available across all variants of an enum. Is this possible? It would certainly be convenient.

David


#2

I’m having a hard time parsing what you’re asking, can you maybe show some made-up code?


#3

@steveklabnik Accessing e.field directly when e is a value of this type:

enum Enum {
    Var1 { field: u32, other: String },
    Var2 { field: u32, different: bool },
}

This isn’t possible, at least at the moment. I guess it might be possible to implement, with laying out the common fields in the enum so that their offset doesn’t depend on the variant.

A common solution is to add a higher-level Struct that contains the Enum (minus common fields) and the common fields. This is what Rust itself does with its AST nodes, for example. The disadvantage is that it gets more cumbersome to pattern-match on nested structures.


#4

Ahh, I see now. Yes, we don’t have anything built-in that would do this right now.


#5

On mobile, but you need to use pattern matching. Ask irc how to destructure enum struct variants.


#6
enum Enum {
    Variant { x: u32, y: u32 },
    Another { a: u8, b: u8 },
}

let u = Enum::Variant { x: 0, y: 0 };

// pattern matching
if let Enum::Variant { x, .. } = u {
    println!("{}", x + x)
}

:wink:


#7

I think what he is after is not having to do a pattern match or have an accessor containing a pattern match if the field is available and identical in all variants.

Now, a syntax extension could possibly expand an enum to include an implementation of accessor methods. You can probably also solve the simple cases of this with just a macro.

Having it be a field access would be more complicated. It would certainly be a language change, and you’d need guaranteed layout of the variant fields.


#8

Another possibility would be to break the type into a struct containing the field and an enum of the other parts.

enum MyEnum {
    Var1 { other: String },
    Var2 { different: bool },
}

struct MyStruct {
    field: u32,
    variants: MyEnum
}

#9

Thanks for the rapid response. Indeed I was thinking in terms of designing a nice API. It would be lovely to not require users to pattern match, but to only require them to read about one type. Sounds like my solution should be to either create an accessor method, or to used a struct holding an enum, which seems clumsy to me. Or to just make people pattern match.

David


#10

I think in this case an accessor method is the nicest way to do it.


#11

Ah, and there I just went with the structs/enum solution in my constants folding helper for clippy :smile: .