9

I find using (1..4)

fn main() {
    for v in (1..4) {
        println!("{}", v);
    }
}

and {1..4}

fn main() {
    for v in {1..4} {
        println!("{}", v);
    }
}

gets the same result. Is there any different semantics between "(1..4)" and "{1..4}" iteration?

Nan Xiao
  • 16,671
  • 18
  • 103
  • 164
  • 1
    The compiler actually gives a warning when parenthesis are used, but not braces. Interesting. https://play.rust-lang.org/?gist=5c648aff16dcedc4ef90bad46087e087&version=stable&backtrace=0 – Akavall Jun 19 '17 at 02:40
  • @Akavall that's because there *are* small differences (see the answers), so it wouldn't be possible to replace every braced expression with a parenthesized one, just most of them. – Shepmaster Jun 19 '17 at 12:06

3 Answers3

10

They produce the same iterators. You can even omit parentheses/braces:

fn main() {
    for v in 1..4 {
        println!("{}", v);
    }
}

You can enclose an expression with () or {} in general. There is a difference however: {} creates a block and you can write statements (like let) in it. There is also a very subtle difference in how expressions are parsed. Edit: I found a blog article that describes another difference in how coercion and borrowck works.

Usually () is preferred if you don't need statements.

Masaki Hara
  • 3,295
  • 21
  • 21
6

There's no real useful difference. Both parenthesis and braces count as a single expression and function to alter the precedence. I'm pretty sure they have slightly different parsing rules, but at that point I'd guess there's a cleaner way of writing the code.

Note that in your examples, the idiomatic way would be to use neither:

fn main() {
    for v in 1..4 {
        println!("{}", v);
    }
}

When needed, I feel I've only ever seen parenthesis used, never braces:

fn main() {
    println!("{}", (1..4).count());
}

There are rare cases where curly braces provide more power. Since they serve to start a new scope, you can use them to "manually" transfer ownership in some tricky locations. For the purposes of the simple iterator described, there won't be any visible difference.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
2

In addition to the existing answers I was interested what the difference would be in the mid-level IR.

Even though the braces introduce a new block, in this case there is virtually no difference even in the (Nightly) MIR - the compiler immediately recognizes that the block serves no other purpose than returning a Range.

ljedrz
  • 20,316
  • 4
  • 69
  • 97