diff --git a/.gitignore b/.gitignore index e871e84..85939f4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *~ *.swp zig-cache/ +answers/ diff --git a/build.zig b/build.zig index d7e09de..916f1a7 100644 --- a/build.zig +++ b/build.zig @@ -236,6 +236,14 @@ const exercises = [_]Exercise{ .output = "Elephant A. Elephant B. Elephant C.", .hint = "Oh no! We forgot Elephant B!", }, + .{ + .main_file = "45_optionals.zig", + .output = "The Ultimate Answer: 42.", + }, + // optional fields (elephant tail - no longer need circular) + // super-simple struct method + // use struct method for elephant tails + // quiz: add elephant trunk (like tail)! }; /// Check the zig version to make sure it can compile the examples properly. diff --git a/exercises/45_optionals.zig b/exercises/45_optionals.zig new file mode 100644 index 0000000..815ba75 --- /dev/null +++ b/exercises/45_optionals.zig @@ -0,0 +1,52 @@ +// +// Sometimes you know that a variable might hold a value or +// it might not. Zig has a neat way of expressing this idea +// called Optionals. An optional type just has a '?' like this: +// +// var foo: ?u32 = 10; +// +// Now foo can store a u32 integer OR null (a value storing +// the cosmic horror of a value NOT EXISTING!) +// +// foo = null; +// +// if (foo == null) beginScreaming(); +// +// Before we can use the optional value as the non-null type +// (a u32 integer in this case), we need to guarantee that it +// isn't null. One way to do this is to THREATEN IT with the +// "orelse" statement. +// +// var bar = foo orelse 2; +// +// Here, bar will either equal the u32 integer value stored in +// foo, or it will equal 2 if foo was null. +// +const std = @import("std"); + +pub fn main() void { + const result = deepThought(); + + // Please threaten the result so that answer is either the + // integer value from deepThought() OR the number 42: + var answer: u8 = result; + + std.debug.print("The Ultimate Answer: {}.\n",.{answer}); +} + +fn deepThought() ?u8 { + // It seems Deep Thought's output has declined in quality. + // But we'll leave this as-is. Sorry Deep Thought. + return null; +} +// +// Blast from the past: +// +// Optionals are a lot like error union types which can either +// hold a value or an error. Likewise, the orelse statement is +// like the catch statement used to "unwrap" a value or supply +// a default value: +// +// var maybe_bad: Error!u32 = Error.Evil; +// var number: u32 = maybe_bad catch 0; +// diff --git a/patches/45_optionals.patch b/patches/45_optionals.patch new file mode 100644 index 0000000..c945b5a --- /dev/null +++ b/patches/45_optionals.patch @@ -0,0 +1,4 @@ +32c32 +< var answer: u8 = result; +--- +> var answer: u8 = result orelse 42; diff --git a/patches/README.md b/patches/README.md new file mode 100644 index 0000000..09fecbd --- /dev/null +++ b/patches/README.md @@ -0,0 +1,9 @@ +# The ziglings/patches Directory + +This is how ziglings is tested. + +The patches fix the broken exercises so that they work again. + +No peeking! :-) + +(Further tooling and explanation goes here.)