| ... | ... | @@ -2179,6 +2179,39 @@ test "@tagName" { |
| 2179 | 2179 | sorts the order of the tag and union field by the largest alignment. |
| 2180 | 2180 | </p> |
| 2181 | 2181 | {#header_close#} |
| 2182 | {#header_open|blocks#} |
| 2183 | <p> |
| 2184 | Blocks are used to limit the scope of variable declarations: |
| 2185 | </p> |
| 2186 | {#code_begin|test_err|undeclared identifier#} |
| 2187 | test "access variable after block scope" { |
| 2188 | { |
| 2189 | var x: i32 = 1; |
| 2190 | } |
| 2191 | x += 1; |
| 2192 | } |
| 2193 | {#code_end#} |
| 2194 | <p>Blocks are expressions. When labeled, <code>break</code> can be used |
| 2195 | to return a value from the block: |
| 2196 | </p> |
| 2197 | {#code_begin|test#} |
| 2198 | const std = @import("std"); |
| 2199 | const assert = std.debug.assert; |
| 2200 | |
| 2201 | test "labeled break from labeled block expression" { |
| 2202 | var y: i32 = 123; |
| 2203 | |
| 2204 | const x = blk: { |
| 2205 | y += 1; |
| 2206 | break :blk y; |
| 2207 | }; |
| 2208 | assert(x == 124); |
| 2209 | assert(y == 124); |
| 2210 | } |
| 2211 | {#code_end#} |
| 2212 | <p>Here, <code>blk</code> can be any name.</p> |
| 2213 | {#see_also|Labeled while|Labeled for#} |
| 2214 | {#header_close#} |
| 2182 | 2215 | {#header_open|switch#} |
| 2183 | 2216 | {#code_begin|test|switch#} |
| 2184 | 2217 | const assert = @import("std").debug.assert; |
| ... | ... | @@ -2374,6 +2407,28 @@ fn rangeHasNumber(begin: usize, end: usize, number: usize) bool { |
| 2374 | 2407 | } else false; |
| 2375 | 2408 | } |
| 2376 | 2409 | {#code_end#} |
| 2410 | {#header_open|Labeled while#} |
| 2411 | <p>When a <code>while</code> loop is labeled, it can be referenced from a <code>break</code> |
| 2412 | or <code>continue</code> from within a nested loop:</p> |
| 2413 | {#code_begin|test#} |
| 2414 | test "nested break" { |
| 2415 | outer: while (true) { |
| 2416 | while (true) { |
| 2417 | break :outer; |
| 2418 | } |
| 2419 | } |
| 2420 | } |
| 2421 | |
| 2422 | test "nested continue" { |
| 2423 | var i: usize = 0; |
| 2424 | outer: while (i < 10) : (i += 1) { |
| 2425 | while (true) { |
| 2426 | continue :outer; |
| 2427 | } |
| 2428 | } |
| 2429 | } |
| 2430 | {#code_end#} |
| 2431 | {#header_close#} |
| 2377 | 2432 | {#header_open|while with Optionals#} |
| 2378 | 2433 | <p> |
| 2379 | 2434 | Just like {#link|if#} expressions, while loops can take an optional as the |
| ... | ... | @@ -2560,6 +2615,37 @@ test "for else" { |
| 2560 | 2615 | }; |
| 2561 | 2616 | } |
| 2562 | 2617 | {#code_end#} |
| 2618 | {#header_open|Labeled for#} |
| 2619 | <p>When a <code>for</code> loop is labeled, it can be referenced from a <code>break</code> |
| 2620 | or <code>continue</code> from within a nested loop:</p> |
| 2621 | {#code_begin|test#} |
| 2622 | const std = @import("std"); |
| 2623 | const assert = std.debug.assert; |
| 2624 | |
| 2625 | test "nested break" { |
| 2626 | var count: usize = 0; |
| 2627 | outer: for ([]i32{ 1, 2, 3, 4, 5 }) |_| { |
| 2628 | for ([]i32{ 1, 2, 3, 4, 5 }) |_| { |
| 2629 | count += 1; |
| 2630 | break :outer; |
| 2631 | } |
| 2632 | } |
| 2633 | assert(count == 1); |
| 2634 | } |
| 2635 | |
| 2636 | test "nested continue" { |
| 2637 | var count: usize = 0; |
| 2638 | outer: for ([]i32{ 1, 2, 3, 4, 5, 6, 7, 8 }) |_| { |
| 2639 | for ([]i32{ 1, 2, 3, 4, 5 }) |_| { |
| 2640 | count += 1; |
| 2641 | continue :outer; |
| 2642 | } |
| 2643 | } |
| 2644 | |
| 2645 | assert(count == 8); |
| 2646 | } |
| 2647 | {#code_end#} |
| 2648 | {#header_close#} |
| 2563 | 2649 | {#header_open|inline for#} |
| 2564 | 2650 | <p> |
| 2565 | 2651 | For loops can be inlined. This causes the loop to be unrolled, which |