From ee9b8fc921f48dc893808e1c9dbfbef321aa362c Mon Sep 17 00:00:00 2001 From: Nguyễn Gia Phong Date: Sun, 28 Feb 2021 17:18:03 +0700 Subject: [lang/zig] Learn some Zig --- lang/zig/defer.zig | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 lang/zig/defer.zig (limited to 'lang/zig/defer.zig') 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 {}; +} -- cgit 1.4.1