diff options
Diffstat (limited to 'lang/zig/defer.zig')
-rw-r--r-- | lang/zig/defer.zig | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/lang/zig/defer.zig b/lang/zig/defer.zig new file mode 100644 index 0000000..754b3af --- /dev/null +++ b/lang/zig/defer.zig @@ -0,0 +1,62 @@ +const std = @import("std"); +const expect = std.testing.expect; +const print = std.debug.print; + +// defer will execute an expression at the end of the current scope. +fn deferExample() usize { + var a: usize = 1; + + { + defer a = 2; + a = 1; + } + expect(a == 2); + + a = 5; + return a; +} + +test "defer basics" { + expect(deferExample() == 5); +} + +// If multiple defer statements are specified, they will be executed in +// the reverse order they were run. +fn deferUnwindExample() void { + print("\n", .{}); + + defer print("1 ", .{}); + defer print("2 ", .{}); + // defers are not run if they are never executed. + if (false) { + defer print("3 ", .{}); + } + // somehow this isn't a scope though? + if (true) { + defer print("4 ", .{}); + } +} + +test "defer unwinding" { + deferUnwindExample(); + print("\n", .{}); +} + +// The errdefer keyword is similar to defer, +// but will only execute if the scope returns with an error. +// +// This is especially useful in allowing a function to clean up properly +// on error, and replaces goto error handling tactics as seen in C. +fn deferErrorExample(is_error: bool) !void { + print("\nstart of function\n", .{}); + // This will always be executed on exit + defer print("end of function\n", .{}); + errdefer print("encountered an error!\n", .{}); + if (is_error) + return error.DeferError; +} + +test "errdefer unwinding" { + deferErrorExample(false) catch {}; + deferErrorExample(true) catch {}; +} |