Jump to a label
In Chapter 2, “Decisions”, we talked about labels, labeled blocks, and even labeled switches. In case you don’t remember, if we label a switch with a symbolic name, (in this case loop: ), we can re-evaluate it with a new value. We do this using continue :label value.
label_jump.zig |
|
const std = @import("std"); const print = std.debug.print; // print the header fn print_header() void { print("\n", .{}); print(" ╔════════════════════════════╗\n", .{}); print(" ║ HIGH SCORES ║\n", .{}); print(" ║____________________________║\n", .{}); } // only print the table footer fn print_footer() void { print(" ╚════════════════════════════╝\n", .{}); } const N_MAX_SCORE = 10000; pub fn main() void { const a_scores = [_]u16{ 9000, 8000, 5000, 4200, 3800 }; print_header(); // initialize the index to the first position var n_i: u8 = 0; loop: switch (a_scores[n_i]) { // in this branch we handle all score cases: 0...N_MAX_SCORE => |n_x| { // print the index and the score print(" ║ {}º | {} pts ║\n", .{ n_i + 1, n_x }); // if the index is smaller than the array length if (n_i < a_scores.len - 1) { // increment the index for the next iteration n_i += 1; // jump to the switch label with the updated score continue :loop a_scores[n_i]; } // if the index exceeds the array positions, we exit }, // if the scores were higher than N_MAX_SCORE // exit -> it’s impossible, someone’s cheating else => unreachable, } print_footer(); } |
|
$ zig run label_jump.zig |
|
╔════════════════════════════╗ ║ HIGH SCORES ║ ║____________________________║ ║ 1º | 9000 pts ║ ║ 2º | 8000 pts ║ ║ 3º | 5000 pts ║ ║ 4º | 4200 pts ║ ║ 5º | 3800 pts ║ ╚════════════════════════════╝ |
The functions print_header and print_footer are helper functions that print the table header and footer, respectively. We've used them to keep the code cleaner.
The really important part, apart from the labeled switch, is when we declare:
|
var n_i: u8 = 0; |
This is a variable we initialize to 0 (the first position) to handle the index of the a_scores array. Before, in the linear_scores_2.zig example, we were incrementing the n_i variable “manually” between each print, every time we wanted to access the next position in the array. Now we do it automatically inside the loop:
|
// if the index is smaller than the length of the array if (n_i < a_scores.len - 1) { // increment the index for the next iteration n_i += 1; // jump to the switch label with the updated score continue :loop a_scores[n_i]; } |
We check that n_i hasn’t gone past the maximum index of the array (.len - 1). If it hasn’t, we increment the variable and jump to the loop: label using continue :loop, passing the value of the next position.
If, on the other hand, n_i was already pointing to the last position of the array, we exit the loop and print the table footer by calling print_footer.