authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-03 14:03:27-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-03 14:03:27-04:00
log27fc49f72c681c0643c2454fe0393abb913703f9
tree2b99dfb64928df97b2a02c400f7d4f092c8a2f50
parent1eda86e1ad46493a996521b7a0c6bd59133960ae

langref: improve docs for while and undefined

closes #1190

1 files changed, 95 insertions(+), 32 deletions(-)

doc/langref.html.in+95-32
...@@ -616,6 +616,17 @@ test "init with undefined" {...@@ -616,6 +616,17 @@ test "init with undefined" {
616 assert(x == 1);616 assert(x == 1);
617}617}
618 {#code_end#}618 {#code_end#}
619 <p>
620 <code>undefined</code> can be {#link|implicitly cast|Implicit Casts#} to any type.
621 Once this happens, it is no longer possible to detect that the value is <code>undefined</code>.
622 <code>undefined</code> means the value could be anything, even something that is nonsense
623 according to the type. Translated into English, <code>undefined</code> means "Not a meaningful
624 value. Using this value would be a bug. The value will be unused, or overwritten before being used."
625 </p>
626 <p>
627 In {#link|Debug#} mode, Zig writes <code>0xaa</code> bytes to undefined memory. This is to catch
628 bugs early, and to help detect use of undefined memory in a debugger.
629 </p>
619 {#header_close#}630 {#header_close#}
620 {#header_close#}631 {#header_close#}
621 {#header_close#}632 {#header_close#}
...@@ -2237,21 +2248,28 @@ test "switch inside function" {...@@ -2237,21 +2248,28 @@ test "switch inside function" {
2237 {#see_also|comptime|enum|@compileError|Compile Variables#}2248 {#see_also|comptime|enum|@compileError|Compile Variables#}
2238 {#header_close#}2249 {#header_close#}
2239 {#header_open|while#}2250 {#header_open|while#}
2251 <p>
2252 A while loop is used to repeatedly execute an expression until
2253 some condition is no longer true.
2254 </p>
2240 {#code_begin|test|while#}2255 {#code_begin|test|while#}
2241const assert = @import("std").debug.assert;2256const assert = @import("std").debug.assert;
22422257
2243test "while basic" {2258test "while basic" {
2244 // A while loop is used to repeatedly execute an expression until
2245 // some condition is no longer true.
2246 var i: usize = 0;2259 var i: usize = 0;
2247 while (i < 10) {2260 while (i < 10) {
2248 i += 1;2261 i += 1;
2249 }2262 }
2250 assert(i == 10);2263 assert(i == 10);
2251}2264}
2265 {#code_end#}
2266 <p>
2267 Use <code>break</code> to exit a while loop early.
2268 </p>
2269 {#code_begin|test|while#}
2270const assert = @import("std").debug.assert;
22522271
2253test "while break" {2272test "while break" {
2254 // You can use break to exit a while loop early.
2255 var i: usize = 0;2273 var i: usize = 0;
2256 while (true) {2274 while (true) {
2257 if (i == 10)2275 if (i == 10)
...@@ -2260,9 +2278,14 @@ test "while break" {...@@ -2260,9 +2278,14 @@ test "while break" {
2260 }2278 }
2261 assert(i == 10);2279 assert(i == 10);
2262}2280}
2281 {#code_end#}
2282 <p>
2283 Use <code>continue</code> to jump back to the beginning of the loop.
2284 </p>
2285 {#code_begin|test|while#}
2286const assert = @import("std").debug.assert;
22632287
2264test "while continue" {2288test "while continue" {
2265 // You can use continue to jump back to the beginning of the loop.
2266 var i: usize = 0;2289 var i: usize = 0;
2267 while (true) {2290 while (true) {
2268 i += 1;2291 i += 1;
...@@ -2272,18 +2295,21 @@ test "while continue" {...@@ -2272,18 +2295,21 @@ test "while continue" {
2272 }2295 }
2273 assert(i == 10);2296 assert(i == 10);
2274}2297}
2298 {#code_end#}
2299 <p>
2300 While loops support a continue expression which is executed when the loop
2301 is continued. The <code>continue</code> keyword respects this expression.
2302 </p>
2303 {#code_begin|test|while#}
2304const assert = @import("std").debug.assert;
22752305
2276test "while loop continuation expression" {2306test "while loop continuation expression" {
2277 // You can give an expression to the while loop to execute when
2278 // the loop is continued. This is respected by the continue control flow.
2279 var i: usize = 0;2307 var i: usize = 0;
2280 while (i < 10) : (i += 1) {}2308 while (i < 10) : (i += 1) {}
2281 assert(i == 10);2309 assert(i == 10);
2282}2310}
22832311
2284test "while loop continuation expression, more complicated" {2312test "while loop continuation expression, more complicated" {
2285 // More complex blocks can be used as an expression in the loop continue
2286 // expression.
2287 var i1: usize = 1;2313 var i1: usize = 1;
2288 var j1: usize = 1;2314 var j1: usize = 1;
2289 while (i1 * j1 < 2000) : ({ i1 *= 2; j1 *= 3; }) {2315 while (i1 * j1 < 2000) : ({ i1 *= 2; j1 *= 3; }) {
...@@ -2291,6 +2317,20 @@ test "while loop continuation expression, more complicated" {...@@ -2291,6 +2317,20 @@ test "while loop continuation expression, more complicated" {
2291 assert(my_ij1 < 2000);2317 assert(my_ij1 < 2000);
2292 }2318 }
2293}2319}
2320 {#code_end#}
2321 <p>
2322 While loops are expressions. The result of the expression is the
2323 result of the <code>else</code> clause of a while loop, which is executed when
2324 the condition of the while loop is tested as false.
2325 </p>
2326 <p>
2327 <code>break</code>, like <code>return</code>, accepts a value
2328 parameter. This is the result of the <code>while</code> expression.
2329 When you <code>break</code> from a while loop, the <code>else</code> branch is not
2330 evaluated.
2331 </p>
2332 {#code_begin|test|while#}
2333const assert = @import("std").debug.assert;
22942334
2295test "while else" {2335test "while else" {
2296 assert(rangeHasNumber(0, 10, 5));2336 assert(rangeHasNumber(0, 10, 5));
...@@ -2299,24 +2339,31 @@ test "while else" {...@@ -2299,24 +2339,31 @@ test "while else" {
22992339
2300fn rangeHasNumber(begin: usize, end: usize, number: usize) bool {2340fn rangeHasNumber(begin: usize, end: usize, number: usize) bool {
2301 var i = begin;2341 var i = begin;
2302 // While loops are expressions. The result of the expression is the
2303 // result of the else clause of a while loop, which is executed when
2304 // the condition of the while loop is tested as false.
2305 return while (i < end) : (i += 1) {2342 return while (i < end) : (i += 1) {
2306 if (i == number) {2343 if (i == number) {
2307 // break expressions, like return expressions, accept a value
2308 // parameter. This is the result of the while expression.
2309 // When you break from a while loop, the else branch is not
2310 // evaluated.
2311 break true;2344 break true;
2312 }2345 }
2313 } else false;2346 } else false;
2314}2347}
2348 {#code_end#}
2349 {#header_open|while with Optionals#}
2350 <p>
2351 Just like {#link|if#} expressions, while loops can take an optional as the
2352 condition and capture the payload. When {#link|null#} is encountered the loop
2353 exits.
2354 </p>
2355 <p>
2356 When the <code>|x|</code> syntax is present on a <code>while</code> expression,
2357 the while condition must have an {#link|Optional Type#}.
2358 </p>
2359 <p>
2360 The <code>else</code> branch is allowed on optional iteration. In this case, it will
2361 be executed on the first null value encountered.
2362 </p>
2363 {#code_begin|test|while#}
2364const assert = @import("std").debug.assert;
23152365
2316test "while null capture" {2366test "while null capture" {
2317 // Just like if expressions, while loops can take an optional as the
2318 // condition and capture the payload. When null is encountered the loop
2319 // exits.
2320 var sum1: u32 = 0;2367 var sum1: u32 = 0;
2321 numbers_left = 3;2368 numbers_left = 3;
2322 while (eventuallyNullSequence()) |value| {2369 while (eventuallyNullSequence()) |value| {
...@@ -2324,8 +2371,6 @@ test "while null capture" {...@@ -2324,8 +2371,6 @@ test "while null capture" {
2324 }2371 }
2325 assert(sum1 == 3);2372 assert(sum1 == 3);
23262373
2327 // The else branch is allowed on optional iteration. In this case, it will
2328 // be executed on the first null value encountered.
2329 var sum2: u32 = 0;2374 var sum2: u32 = 0;
2330 numbers_left = 3;2375 numbers_left = 3;
2331 while (eventuallyNullSequence()) |value| {2376 while (eventuallyNullSequence()) |value| {
...@@ -2333,18 +2378,6 @@ test "while null capture" {...@@ -2333,18 +2378,6 @@ test "while null capture" {
2333 } else {2378 } else {
2334 assert(sum1 == 3);2379 assert(sum1 == 3);
2335 }2380 }
2336
2337 // Just like if expressions, while loops can also take an error union as
2338 // the condition and capture the payload or the error code. When the
2339 // condition results in an error code the else branch is evaluated and
2340 // the loop is finished.
2341 var sum3: u32 = 0;
2342 numbers_left = 3;
2343 while (eventuallyErrorSequence()) |value| {
2344 sum3 += value;
2345 } else |err| {
2346 assert(err == error.ReachedZero);
2347 }
2348}2381}
23492382
2350var numbers_left: u32 = undefined;2383var numbers_left: u32 = undefined;
...@@ -2355,6 +2388,35 @@ fn eventuallyNullSequence() ?u32 {...@@ -2355,6 +2388,35 @@ fn eventuallyNullSequence() ?u32 {
2355 };2388 };
2356}2389}
23572390
2391 {#code_end#}
2392 {#header_close#}
2393
2394 {#header_open|while with Error Unions#}
2395 <p>
2396 Just like {#link|if#} expressions, while loops can take an error union as
2397 the condition and capture the payload or the error code. When the
2398 condition results in an error code the else branch is evaluated and
2399 the loop is finished.
2400 </p>
2401 <p>
2402 When the <code>else |x|</code> syntax is present on a <code>while</code> expression,
2403 the while condition must have an {#link|Error Union Type#}.
2404 </p>
2405 {#code_begin|test|while#}
2406const assert = @import("std").debug.assert;
2407
2408test "while error union capture" {
2409 var sum1: u32 = 0;
2410 numbers_left = 3;
2411 while (eventuallyErrorSequence()) |value| {
2412 sum1 += value;
2413 } else |err| {
2414 assert(err == error.ReachedZero);
2415 }
2416}
2417
2418var numbers_left: u32 = undefined;
2419
2358fn eventuallyErrorSequence() error!u32 {2420fn eventuallyErrorSequence() error!u32 {
2359 return if (numbers_left == 0) error.ReachedZero else blk: {2421 return if (numbers_left == 0) error.ReachedZero else blk: {
2360 numbers_left -= 1;2422 numbers_left -= 1;
...@@ -2362,6 +2424,7 @@ fn eventuallyErrorSequence() error!u32 {...@@ -2362,6 +2424,7 @@ fn eventuallyErrorSequence() error!u32 {
2362 };2424 };
2363}2425}
2364 {#code_end#}2426 {#code_end#}
2427 {#header_close#}
23652428
2366 {#header_open|inline while#}2429 {#header_open|inline while#}
2367 <p>2430 <p>