diff --git a/doc/langref.html.in b/doc/langref.html.in index 1da4205b89..3cdcdc6e88 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -616,6 +616,17 @@ test "init with undefined" { assert(x == 1); } {#code_end#} +

+ undefined can be {#link|implicitly cast|Implicit Casts#} to any type. + Once this happens, it is no longer possible to detect that the value is undefined. + undefined means the value could be anything, even something that is nonsense + according to the type. Translated into English, undefined means "Not a meaningful + value. Using this value would be a bug. The value will be unused, or overwritten before being used." +

+

+ In {#link|Debug#} mode, Zig writes 0xaa bytes to undefined memory. This is to catch + bugs early, and to help detect use of undefined memory in a debugger. +

{#header_close#} {#header_close#} {#header_close#} @@ -2237,21 +2248,28 @@ test "switch inside function" { {#see_also|comptime|enum|@compileError|Compile Variables#} {#header_close#} {#header_open|while#} +

+ A while loop is used to repeatedly execute an expression until + some condition is no longer true. +

{#code_begin|test|while#} const assert = @import("std").debug.assert; test "while basic" { - // A while loop is used to repeatedly execute an expression until - // some condition is no longer true. var i: usize = 0; while (i < 10) { i += 1; } assert(i == 10); } + {#code_end#} +

+ Use break to exit a while loop early. +

+ {#code_begin|test|while#} +const assert = @import("std").debug.assert; test "while break" { - // You can use break to exit a while loop early. var i: usize = 0; while (true) { if (i == 10) @@ -2260,9 +2278,14 @@ test "while break" { } assert(i == 10); } + {#code_end#} +

+ Use continue to jump back to the beginning of the loop. +

+ {#code_begin|test|while#} +const assert = @import("std").debug.assert; test "while continue" { - // You can use continue to jump back to the beginning of the loop. var i: usize = 0; while (true) { i += 1; @@ -2272,18 +2295,21 @@ test "while continue" { } assert(i == 10); } + {#code_end#} +

+ While loops support a continue expression which is executed when the loop + is continued. The continue keyword respects this expression. +

+ {#code_begin|test|while#} +const assert = @import("std").debug.assert; test "while loop continuation expression" { - // You can give an expression to the while loop to execute when - // the loop is continued. This is respected by the continue control flow. var i: usize = 0; while (i < 10) : (i += 1) {} assert(i == 10); } test "while loop continuation expression, more complicated" { - // More complex blocks can be used as an expression in the loop continue - // expression. var i1: usize = 1; var j1: usize = 1; while (i1 * j1 < 2000) : ({ i1 *= 2; j1 *= 3; }) { @@ -2291,6 +2317,20 @@ test "while loop continuation expression, more complicated" { assert(my_ij1 < 2000); } } + {#code_end#} +

+ While loops are expressions. The result of the expression is the + result of the else clause of a while loop, which is executed when + the condition of the while loop is tested as false. +

+

+ break, like return, accepts a value + parameter. This is the result of the while expression. + When you break from a while loop, the else branch is not + evaluated. +

+ {#code_begin|test|while#} +const assert = @import("std").debug.assert; test "while else" { assert(rangeHasNumber(0, 10, 5)); @@ -2299,24 +2339,31 @@ test "while else" { fn rangeHasNumber(begin: usize, end: usize, number: usize) bool { var i = begin; - // While loops are expressions. The result of the expression is the - // result of the else clause of a while loop, which is executed when - // the condition of the while loop is tested as false. return while (i < end) : (i += 1) { if (i == number) { - // break expressions, like return expressions, accept a value - // parameter. This is the result of the while expression. - // When you break from a while loop, the else branch is not - // evaluated. break true; } } else false; } + {#code_end#} + {#header_open|while with Optionals#} +

+ Just like {#link|if#} expressions, while loops can take an optional as the + condition and capture the payload. When {#link|null#} is encountered the loop + exits. +

+

+ When the |x| syntax is present on a while expression, + the while condition must have an {#link|Optional Type#}. +

+

+ The else branch is allowed on optional iteration. In this case, it will + be executed on the first null value encountered. +

+ {#code_begin|test|while#} +const assert = @import("std").debug.assert; test "while null capture" { - // Just like if expressions, while loops can take an optional as the - // condition and capture the payload. When null is encountered the loop - // exits. var sum1: u32 = 0; numbers_left = 3; while (eventuallyNullSequence()) |value| { @@ -2324,8 +2371,6 @@ test "while null capture" { } assert(sum1 == 3); - // The else branch is allowed on optional iteration. In this case, it will - // be executed on the first null value encountered. var sum2: u32 = 0; numbers_left = 3; while (eventuallyNullSequence()) |value| { @@ -2333,18 +2378,6 @@ test "while null capture" { } else { assert(sum1 == 3); } - - // Just like if expressions, while loops can also take an error union as - // the condition and capture the payload or the error code. When the - // condition results in an error code the else branch is evaluated and - // the loop is finished. - var sum3: u32 = 0; - numbers_left = 3; - while (eventuallyErrorSequence()) |value| { - sum3 += value; - } else |err| { - assert(err == error.ReachedZero); - } } var numbers_left: u32 = undefined; @@ -2355,6 +2388,35 @@ fn eventuallyNullSequence() ?u32 { }; } + {#code_end#} + {#header_close#} + + {#header_open|while with Error Unions#} +

+ Just like {#link|if#} expressions, while loops can take an error union as + the condition and capture the payload or the error code. When the + condition results in an error code the else branch is evaluated and + the loop is finished. +

+

+ When the else |x| syntax is present on a while expression, + the while condition must have an {#link|Error Union Type#}. +

+ {#code_begin|test|while#} +const assert = @import("std").debug.assert; + +test "while error union capture" { + var sum1: u32 = 0; + numbers_left = 3; + while (eventuallyErrorSequence()) |value| { + sum1 += value; + } else |err| { + assert(err == error.ReachedZero); + } +} + +var numbers_left: u32 = undefined; + fn eventuallyErrorSequence() error!u32 { return if (numbers_left == 0) error.ReachedZero else blk: { numbers_left -= 1; @@ -2362,6 +2424,7 @@ fn eventuallyErrorSequence() error!u32 { }; } {#code_end#} + {#header_close#} {#header_open|inline while#}