From c70fa5f58f5ca2dc010f00caee19027069a09131 Mon Sep 17 00:00:00 2001 From: Dave Gauer Date: Sun, 31 Jan 2021 17:48:34 -0500 Subject: Adding exs 27-32 --- 29_errdefer.zig | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 29_errdefer.zig (limited to '29_errdefer.zig') diff --git a/29_errdefer.zig b/29_errdefer.zig new file mode 100644 index 0000000..cd2158d --- /dev/null +++ b/29_errdefer.zig @@ -0,0 +1,60 @@ +// +// Another common problem is a block of code that could exit in multiple +// places due to an error - but that needs to run do something before it +// exits (typically to clean up after itself). +// +// An "errdefer" is a defer that only runs if the block exits with an error: +// +// { +// errdefer cleanup(); +// try canFail(); +// } +// +// The cleanup() function is called ONLY if the "try" statement returns an +// error produced by canFail(). +// +const std = @import("std"); + +// +var counter: u32 = 0; + +const MyErr = error{ GetFail, IncFail }; + +pub fn main() void { + // We simply quit the entire program if we fail to get a number: + var a: u32 = makeNumber() catch return; + var b: u32 = makeNumber() catch return; + + std.debug.print("Numbers: {}, {}\n", .{a,b}); +} + +fn makeNumber() MyErr!u32 { + std.debug.print("Getting number...", .{}); + + // Please make the "failed" message print ONLY if the makeNumber() + // function exits with an error: + std.debug.print("failed!\n", .{}); + + var num = try getNumber(); // <-- This could fail! + + num = try increaseNumber(num); // <-- This could ALSO fail! + + std.debug.print("got {}. ", .{num}); + + return num; +} + +fn getNumber() MyErr!u32 { + // I _could_ fail...but I don't! + return 4; +} + +fn increaseNumber(n: u32) MyErr!u32 { + // I fail after the first time you run me! + if (counter > 0) return MyErr.IncFail; + + // Sneaky, weird global stuff. + counter += 1; + + return n + 1; +} -- cgit v1.2.3-ZIG