Struct directly inside and enum?

Dumb question time.

I am messing with some old code, that I didn't write. (That I think could maybe have been more clear…) There is an enum declaration that seems to have structs embedded directly inside. Here is a simplified example:

pub enum MyEnum {
    Foo { thing: String },
    Bar { thang: u32, thud: u32 },
}

At least I think those are structs inside. Anyway, given such syntax, how do I create such a beast? I can't figure out the correct syntax.

Some of my attempts.

Thanks,

-kb, the Kent who thinks he is understanding Rust and then something like this brings him to a screeching halt.

Like this:

// I added this for `dbg!()` to work
#[derive(Debug)]
pub enum MyEnum {
    Foo { thing: String },
    Bar { thang: u32, thud: u32 },
}

fn main() {
    let x = MyEnum::Foo{ thing: String::from("this") };
    dbg!(x);
    let x = MyEnum::Bar{ thang: 4, thud: 7 };
    dbg!(x);
}

More info about enums (and other) can be found in the book.

So the Foo or the Bar in that syntax kind of does double-duty. It is both the variant and the creation of the new struct, and the parentheses that I thought were part of declaring an enum vanish in this special case. If I break out the definition into a distinct struct the syntax is different and the parentheses seem to be necessary again. I think.

This feels like one of those things that Rust programmers like to think of as harmless syntax sugar that makes for a better quality of life for programmers! But I think Rust is too big a language for being too clever with too many such things. (An enum declaration that doesn't need any parentheses‽‽)

The enum part of The Book? I didn't see any examples of structs being embedded directly without being defined on their own. Maybe they are there… Grrr.

Enough grumbling on my part.

Thanks!

-kb, the Kent who sincerely appreciates being unstuck.

You can make your own unit structs, tuple structs, and nominal structs.

struct Foo;
struct Bar(u32);
struct Baz(u32, i32);
struct Quz { a: u32, b: i32 }

And you can have enum variants that mirror all of those.

enum Enum {
    Foo,
    Bar(u32),
    Baz(u32, i32),
    Quz { a: u32, b: i32 },
}

Enum variants aren't their own types and there are some other quirks, but consistency here is pretty high IMO.

1 Like

Can you declare an instance of one of those with that same parentheses-free syntax? My attempt failed.

-kb

You mean make values of the Enum? Sure.

    let _ = Enum::Foo;
    let _ = Enum::Foo { };
    let _ = Enum::Bar(42);
    let _ = Enum::Bar { 0: 42 };
    let _ = Enum::Baz(13, 31);
    let _ = Enum::Baz { 0: 13, 1: 31 };
    let _ = Enum::Quz { a: 7, b: 49 };

(This also demonstrates the general ADT syntax where you can use a braced form for unit and tuple variants. I'm not sure where that's officially documented.)

1 Like

https://doc.rust-lang.org/book/ch06-01-defining-an-enum.html

There is a enum Message with a variant of every kind, but an example of constructing the struct-like variant seems to be missing.

1 Like

Incidentally, the same forms work for the structs.

    let _ = Foo;
    let _ = Foo { };
    let _ = Bar(42);
    let _ = Bar { 0: 42 };
    let _ = Baz(13, 31);
    let _ = Baz { 0: 13, 1: 31 };
    let _ = Quz { a: 7, b: 49 };
1 Like

So it is not a special case only for structs that are not distinctly defined.

Hmmm.

Thanks,

-kb