Why Comma After Enum Value In Output

I don't really like that when I use #[derive(Debug)] on an enum and print it, it prints a comma after the value of the enum type. I don't understand why, because that's not an array, so the comma doesn't separate any values.

Here is the code:

#[derive(Debug)]
enum Foo {
    Bar(String)
}

fn main() {
    let foo = Foo::Bar(String::from("Hello"));
    println!("{:#?}", foo);
}

It prints:

Bar(
    "Hello",
)  //      ^ Why this?

In my opinion, it looks a bit ugly. Is it there, because it's on a new line? Is it like a separator of statements like the semicolon?

Is there anybody that thinks that this comma is redundant and ugly? I'm the only one in the community who thinks like that? I understand that commas like the last one in this example have some advantages like consistency and for diffs:

struct Point {
    x: f32,
    y: f32,
    z: f32,
}

But in the previous case that is output to the terminal, not source code, so I find no reason for that comma to be there.

1 Like

When it prints the fields on their own lines, it always adds a comma.

1 Like

It's exactly for easier machine-readability and machine-printability that types allow trailing commas in both their source code representation and in the similar-looking derived Debug representation. If one can always just expect or emit a comma even after the last element, then this simplifies the writer/parser code as there's no need for special-casing the last item.

2 Likes

As a side note, you're pretty printing the Debug representation of foo. To print the normal Debug representation you need to use {:?}

I understand now...

But as an example, this output from my program is a bit hard to read, because of the trailing commas:

{ 
         " n a m e " :   " S i m o n " , 
         " a g e " :   1 8 , 
         " a r r a y " :   [ 1 ,   2 ,   3 ] 
 } 
 [
    LeftBrace,
    String(
        "name",
    ),
    Colon,
    String(
        "Simon",
    ),
    Comma,
    String(
        "age",
    ),
    Colon,
    Number(
        "18",
    ),
    String(
        "array",
    ),
    Colon,
    LeftBracket,
    Number(
        "1",
    ),
    Number(
        "2",
    ),
    Number(
        "3",
    ),
    RightBrace,
]

I'm talking about the array of enums.

I know that. I wanted the array elements to be on a separate line. (I'm talking about an array of enum values.)

Ok, but in this case "Hello" is not a field, it's a value. Am I wrong?

It's a value stored in the field. The Bar(String) is a tuple variant of an enum with single field of String type.

Oh... Now I get it. I didn't know you can have multiple values in an enum type. Or maybe I knew, but I forgot. So Bar can have two "fields", two "values".

You can look at it that way, but you can also look at it as one value still -- a tuple. (The tuple may contain more than one field). Or it could be a value with named fields instead:

enum MyEnum {
    NoValue,
    OneFieldTuple(String),
    TwoFieldTuple(usize, isize),
    NamedSubFields { x: i32, y: Option<bool> },
}

(A downside of this mental model is that enum variants are not themselves types.)

2 Likes

yet

2 Likes