// // Loop bodies are blocks, which are also expressions. We've seen // how they can be used to evaluate and return values. To further // expand on this concept, it turns out we can also give names to // blocks by applying a 'label': // // my_label: { ... } // // Once you give a block a label, you can use 'break' to exit // from that block. // // outer_block: { // outer block // while (true) { // inner block // break :outer_block; // } // unreachable; // } // // As we've just learned, you can return a value using a break // statement. Does that mean you can return a value from any // labeled block? Yes it does! // // const foo = make_five: { // const five = 1 + 1 + 1 + 1 + 1; // break :make_five five; // }; // // Labels can also be used with loops. Being able to break out of // nested loops at a specific level is one of those things that // you won't use every day, but when the time comes, it's // incredibly convenient. Being able to return a value from an // inner loop is sometimes so handy, it almost feels like cheating // (and can help you avoid creating a lot of temporary variables). // // const bar: u8 = two_loop: while (true) { // while (true) { // break :two_loop 2; // } // } else 0; // // In the above example, the break exits from the outer loop // labeled "two_loop" and returns the value 2. The else clause is // attached to the outer two_loop and would be evaluated if the // loop somehow ended without the break having been called. // // Finally, you can also use block labels with the 'continue' // statement: // // my_while: while (true) { // continue :my_while; // } // const print = @import("std").debug.print; // As mentioned before, we'll soon understand why these two // numbers don't need explicit types. Hang in there! const ingredients = 4; const foods = 4; const Food = struct { name: []const u8, requires: [ingredients]bool, }; // Chili Macaroni Tomato Sauce Cheese // ------------------------------------------------------ // Mac & Cheese x x // Chili Mac x x // Pasta x x // Cheesy Chili x x // ------------------------------------------------------ const menu: [foods]Food = [_]Food{ Food{ .name = "Mac & Cheese", .requires = [ingredients]bool{ false, true, false, true }, }, Food{ .name = "Chili Mac", .requires = [ingredients]bool{ true, true, false, false }, }, Food{ .name = "Pasta", .requires = [ingredients]bool{ false, true, true, false }, }, Food{ .name = "Cheesy Chili", .requires = [ingredients]bool{ true, false, false, true }, }, }; pub fn main() void { // Welcome to Cafeteria USA! Choose your favorite ingredients // and we'll produce a delicious meal. // // Cafeteria Customer Note: Not all ingredient combinations // make a meal. The default meal is macaroni and cheese. // // Software Developer Note: Hard-coding the ingredient // numbers (based on array position) will be fine for our // tiny example, but it would be downright criminal in a real // application! const wanted_ingredients = [_]u8{ 0, 3 }; // Chili, Cheese // Look at each Food on the menu... var meal = food_loop: for (menu) |food| { // Now look at each required ingredient for the Food... for (food.requires) |required, required_ingredient| { // This ingredient isn't required, so skip it. if (!required) continue; // See if the customer wanted this ingredient. // (Remember that want_it will be the index number of // the ingredient based on its position in the // required ingredient list for each food.) var found = for (wanted_ingredients) |want_it| { if (required_ingredient == want_it) break true; } else false; // We did not find this required ingredient, so we // can't make this Food. Continue the outer loop. if (!found) continue :food_loop; } // If we get this far, the required ingredients were all // wanted for this Food. // // Please return this Food from the loop. break; }; // ^ Oops! We forgot to return Mac & Cheese as the default // Food when the requested ingredients aren't found. print("Enjoy your {s}!\n", .{meal.name}); } // Challenge: You can also do away with the 'found' variable in // the inner loop. See if you can figure out how to do that!