Trailing Commas


#1

Throughout “The Rust Programming Language”, trailing commas are used in the examples, seemingly anywhere there is a comma-separated list… i.e.:

enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i32), // <-- Trailing comma
}

Are those necessary? Do they change the functionality similar to having a trailing semi-colon versus leaving it off changes from a statement to an expression? Or is this just a preference to make it easier to add items onto the list later?


#2

They are optional, but considered good style.

No one will call you out on not using them, though :).


#3

No.

No.

Yes.


#4

Thanks @skade and @notriddle!


#5

Just to add to the other comments in this thread with a possible rationale. Adding a trailing comma can ease refactoring. Rust doesn’t (yet) have amazing IDE support and forgetting to add a comma when adding a new field can feel a bit like a papercut.


#6

More importantly, line-by-line diffs (like GitHub uses) will mark fewer lines as changed when you use trailing commas.


#7

Just one thing: If you use them religiously, you will frequently run into the fact that they cannot be used with:

  • panic!()
  • assert_eq!()
  • …and quite frankly, in my experience, any other macro not written by me.

(I mean, c’mon, really! We’re almost at Rust 1.22 and counting! Can this not be fixed at least in the stdlib?!)


Edit:

ExpHP’s magical guide to supporting a trailing comma

  1. See vec![].

#8

I usually just put a $(,)* at the end.


#9

I secretly do that everywhere for internal macros, but for anything user-facing I’d probably want it to give an error on two commas.


#10

I posted a comprehensive report on all unsupported trailing commas in std macros to internals.

I’m glad to report that assert_eq! has apparently been fixed in the upcoming release!