If match has no return value, should I use an `;` or not?


#1

Another question about writing idiomatic Rust code. Taken two examples from https://doc.rust-lang.org/book/match.html I wonder what is more idiomatic when I use pattern matching without using a return value: append a ; or not?

Example 1:

let x = 5;

match x {
    1 => println!("one"),
    2 => println!("two"),
    3 => println!("three"),
    4 => println!("four"),
    5 => println!("five"),
    _ => println!("something else"),
}  // no ;

Example 2:

fn process_message(msg: Message) {
    match msg {
        Message::Quit => quit(),
        Message::ChangeColor(r, g, b) => change_color(r, g, b),
        Message::Move { x: x, y: y } => move_cursor(x, y),
        Message::Write(s) => println!("{}", s),
    };
};  // with ;

Is there a preferred style?


#2

I wouldn’t, just like I wouldn’t put a semicolon after an if expression.


#3

In C a ; would be a null statement which would equate to the assembly instruction NOP (no operation) which would still execute a machine instruction. Typically a compiler is not required to generate the NOP and will most likely not actually generate the operation. There may be some exeption such as:

for(int i=0; i<10; ++i)
;

where the NOP would be required so that the for loop will work. The compiler however would likely decide to completely omitt the for loop as it doesn’t actually do anything. You could probabely (I din’t test it) write something like this:

int main()
{
while(true)
;
}

and get an endless loop where the NOP is actually used. So, given a reasonable compiler in your case it won’t make a difference. However, technically you don’t want to have statements that are unnecessary. I would argue that it is nice practice to not write the ; unless it is actually required. I don’t know about how rust handles this. My background is more C-based (QT, C#). In your case I would say the prefered style is more likely to not use the ; after the pattern matching. I wouldn’t use it.


#4

Unlike C, Rust doesn’t allow you to omit the braces on those constructs; the semicolon doesn’t make a difference.


#5

Fair enough. I was thinking that the match is finished with the closing }. So that you end up with:

let x = 2;
match x {
1 => println!(“one”),
2 => println!(“two”),
_ => println!(“something else”),
};

is equal to:

let x = 2;
match x {
1 => println!(“one”),
2 => println!(“two”),
_ => println!(“something else”),
} // match ended here
; // this is a null statement (NOP)

Hence me arguing that it’s a nicer style not to have the ; at all. Given my reasoning above. I agree that after compiling you get the exact same result. It’s only about style. I just wanted to give a reason why I would choose that style.


#6

Right, I’m just saying that while in C you can write while (TRUE); in Rust you have to write while true {}


#7

In Rust, you use loop {} instead of while true.