Rust匹配语句是否需要逗号?

时间:2018-08-02 22:13:00

标签: syntax rust

为什么此代码有效?比赛陈述中的逗号只是惯例吗?

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])
                 }
}

2 个答案:

答案 0 :(得分:14)

让我们看看the Rust reference says about this

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

我们可以在这里看到的是,=>的右侧始终有一个表达式,但是我们区分了两种类型的表达式: BlockExpression Expression 。在 BlockExpression 之后,逗号是可选的(用?表示),但是在正则表达式之后,除了最后一个匹配臂之外,逗号也是必需的:那里,逗号始终是可选的。

什么是 BlockExpression The reference基本上将其定义为两个大括号{ },并带有语句列表和可选的tail表达式。

因此:如果满足以下条件,则在比赛末尾的逗号是可选的

  • 这是最后一个匹配项
  • 如果手臂的右手是块表达式(两个大括号{}之间的东西)。

不幸的是,编译器与参考文献不太一致。例如,这可行:

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

请注意,第一个匹配臂的右侧不是块表达式,而是if-else-expression。因此,对于编译器而言,规则似乎是:如果右侧以右括号}结尾,则逗号是可选的。


关于惯用语

  • 如果右侧以右括号}结尾,请省略逗号。
  • 如果不是,请使用逗号,即使它是最后一个匹配项。

答案 1 :(得分:6)

  

Rust匹配语句是否需要逗号?

不。 您自己的代码证明了这一点

  

为什么此代码有效?

因为语言的设计者决定应该这样做。

匹配臂可以带有后跟逗号的表达式,也可以具有不带逗号的块。

  

匹配语句中的逗号是否只是约定?

不。使用花括号时,rustfmt会删除逗号。否则,它们是必需

rustfmt如何放置您的代码:

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])
        }
    }
}