Do Rust match statements require commas?

  • A+

Why does this code work? Are commas in match statements just a convention?

for (index, character) in argv[1].chars().enumerate() { match character {     'a' | 'A' => {println!("{}: 'A'", index)}     'e' | 'E' => {println!("{}: 'E'", index)}     'i' | 'I' => {println!("{}: 'I'", index)}     'o' | 'O' => {println!("{}: 'O'", index)}     'u' | 'U' => {println!("{}: 'U'", index)}      _        => {                      let consonant: Vec<_> = character.to_uppercase().collect();                      println!("{}: {:?} is not a vowel", index, consonant[0])                  } } 


Let's take a look what the Rust reference says about this:

MatchArms :    ( MatchArm => ( BlockExpression ,? | Expression , ) )*    MatchArm => ( BlockExpression | Expression ) ,? 

What we can see here is that on the right side of => there is always an expression, but we distinguish between two types of expressions: BlockExpression and Expression. After a BlockExpression a comma is optional (denoted by the ?), but after an normal expression the comma is required, except for the last match arm: there, the comma is always optional.

What is a BlockExpression? The reference defines it as basically two braces { } with a list of statements and an optional tail expression.

So: commas at the end of match arms are optional if:

  • it is the last match arm, or
  • if the right hand side of the arm is a block expression (stuff between two braces {}).

Unfortunately, the compiler doesn't quite agree with the reference. This works, for example:

match true {     false => if true {         "hi"     } else {         "no"     }     true => "" }; 

Note that the right hand side of the first match arm is not a block expression, but an if-else-expression. So for the compiler the rule seems to be: if the right hand side ends with a closing brace }, the comma is optional.

As for what is idiomatic:

  • If the right hand side ends with a closing brace }, omit the comma.
  • If not: use a comma, even when it's the last match arm.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: