Is {} mandatory in "for" loop?

Hello,
In the following code why the second for need {}? The second for just has one command.

fn main() {
let mut x = [[0;10];4];
    for i in 0..4 {
		for j in 0..10 {
			x[i][j]=0;
			}
		}
}

Thank you.

Yes. In C, the {} are optional, but the () around the loop condition are mandatory. However, Rust has made the opposite choice where {} is required and () is optional.

It's not really possible to make both optional. It makes parsing the language ambiguous.

6 Likes

Yes. Rust has decided its syntax works this way.

All questions of the form "Why does Rust does not copy feature X from language Y" have similar answers.

  • Rust is not language Y. All languages have different sets of features and different design decisions. That fact should not be surprising. If you like a different set of features (ideally, semantics are more important to you than syntax), then you can use a different language. Because different people have different preferences, it should not be a surprise that Rust does not have all your favourite features, it certainly does not have all my favourite features.
  • If you want to understand the complete reason for particular decisions of language design, the statement "This feature is nice for this particular snippet" is not enough. Following this statement would lead to languages feeling like patchwork. Rust is not perfect, but also not intentionally bad (almost all languages are not intentionally bad).

I let others argue here about the reasoning for this particular design decision.

1 Like

By the way, there are excellent reasons to make {} mandatory. From the Linux kernel coding style:

Don’t put multiple statements on a single line unless you have something to hide:

if (condition) do_this;
  do_something_everytime;

When the {} is mandatory, you cannot do this kind of thing.

5 Likes

Here's an excellent real-life reason why.

6 Likes

I for one am very happy that Rust does require those {} around single statements. I'm all in favour of consistency. The "principle of least surprises" as they say. Those surprises have often annoyed me in C.

Note that the match statement allows single expressions without braces:

fn main() {
    match 2 {
        1 => {
            println!("One");
        }
        2 => println!("Two"), // no braces, but comma required at end
        3 => {
            println!("Three");
        }
        _ => {
            println!("Many or none or negative");
        }
    }
}

(Playground)

Hmm.. still, match is consistent with if, for, in that it requires {}even if there is only one match arm:

    enum X {
        A(u32),
    }

    let y = match t {
        X::A(z) => z,
    };

As useless as that may be...

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.