mirror of
https://codeberg.org/andyscott/ziglings.git
synced 2024-12-22 14:03:10 -05:00
Add ex 50 'no values' (help further address #25)
This commit is contained in:
parent
0552a62896
commit
28791f0cb8
3 changed files with 102 additions and 1 deletions
|
@ -260,7 +260,10 @@ const exercises = [_]Exercise{
|
||||||
.output = "A B C Cv Bv Av",
|
.output = "A B C Cv Bv Av",
|
||||||
.hint = "Now you're writting Zig!",
|
.hint = "Now you're writting Zig!",
|
||||||
},
|
},
|
||||||
// 50 null vs undefined
|
.{
|
||||||
|
.main_file = "50_no_value.zig",
|
||||||
|
.output = "That is not dead which can eternal lie / And with strange aeons even death may die.",
|
||||||
|
},
|
||||||
// 51 pass-by-value and const fn params
|
// 51 pass-by-value and const fn params
|
||||||
// 52 slices!
|
// 52 slices!
|
||||||
};
|
};
|
||||||
|
|
84
exercises/50_no_value.zig
Normal file
84
exercises/50_no_value.zig
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
//
|
||||||
|
// "We live on a placid island of ignorance in the midst
|
||||||
|
// of black seas of infinity, and it was not meant that
|
||||||
|
// we should voyage far."
|
||||||
|
//
|
||||||
|
// from The Call of Cthulhu
|
||||||
|
// by H. P. Lovecraft
|
||||||
|
//
|
||||||
|
// Zig has at least four ways of expressing "no value":
|
||||||
|
//
|
||||||
|
// * undefined
|
||||||
|
//
|
||||||
|
// var foo: u8 = undefined;
|
||||||
|
//
|
||||||
|
// "undefined" should not be thought of as a value, but as a way
|
||||||
|
// of telling the compiler that you are not assigning a value
|
||||||
|
// _yet_. Any type may be set to undefined, but attempting
|
||||||
|
// to read or use that value is _always_ a mistake.
|
||||||
|
//
|
||||||
|
// * null
|
||||||
|
//
|
||||||
|
// var foo: ?u8 = null;
|
||||||
|
//
|
||||||
|
// The "null" primitive value _is_ a value that means "no value".
|
||||||
|
// This is typically used with optional types as with the ?u8
|
||||||
|
// shown above. When foo equals null, that's not a value of type
|
||||||
|
// u8. It means there is _no value_ of type u8 in foo at all!
|
||||||
|
//
|
||||||
|
// * error
|
||||||
|
//
|
||||||
|
// var foo: MyError!u8 = BadError;
|
||||||
|
//
|
||||||
|
// Errors are _very_ similar to nulls. They _are_ a value, but
|
||||||
|
// they usually indicate that the "real value" you were looking
|
||||||
|
// for does not exist. Instead, you have an error. The example
|
||||||
|
// error union type of MyError!u8 means that foo either holds
|
||||||
|
// a u8 value OR an error. There is _no value_ of type u8 in foo
|
||||||
|
// when it's set to an error!
|
||||||
|
//
|
||||||
|
// * void
|
||||||
|
//
|
||||||
|
// var foo: void = {};
|
||||||
|
//
|
||||||
|
// "void" is a _type_, not a value. It is the most popular of the
|
||||||
|
// Zero Bit Types (those types which take up absolutely no space
|
||||||
|
// and have only a semantic value. When compiled to executable
|
||||||
|
// code, zero bit types generate no code at all. The above example
|
||||||
|
// shows a variable foo of type void which is assigned the value
|
||||||
|
// of an empty expression. It's much more common to see void as
|
||||||
|
// the return type of a function that returns nothing.
|
||||||
|
//
|
||||||
|
// Zig has all of these ways of expressing different types of "no value"
|
||||||
|
// because they each serve a purpose. Briefly:
|
||||||
|
//
|
||||||
|
// * undefined - there is no value YET, this cannot be read YET
|
||||||
|
// * null - there is an explicit value of "no value"
|
||||||
|
// * errors - there is no value because something went wrong
|
||||||
|
// * void - there will NEVER be a value stored here
|
||||||
|
//
|
||||||
|
// Please use the correct "no value" for each ??? to make this program
|
||||||
|
// print out a cursed quote from the Necronomicon. ...If you dare.
|
||||||
|
//
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const Err = error{Cthulhu};
|
||||||
|
|
||||||
|
pub fn main() void {
|
||||||
|
var first_line1: *const [16]u8 = ???;
|
||||||
|
first_line1 = "That is not dead";
|
||||||
|
|
||||||
|
var first_line2: Err!*const [21]u8 = ???;
|
||||||
|
first_line2 = "which can eternal lie";
|
||||||
|
|
||||||
|
std.debug.print("{s} {s} / ", .{ first_line1, first_line2 });
|
||||||
|
|
||||||
|
printSecondLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn printSecondLine() ??? {
|
||||||
|
var second_line2: ?*const [18]u8 = ???;
|
||||||
|
second_line2 = "even death may die";
|
||||||
|
|
||||||
|
std.debug.print("And with strange aeons {s}.\n", .{second_line2.?});
|
||||||
|
}
|
14
patches/patches/50_no_value.patch
Normal file
14
patches/patches/50_no_value.patch
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
68c68
|
||||||
|
< var first_line1: *const [16]u8 = ???;
|
||||||
|
---
|
||||||
|
> var first_line1: *const [16]u8 = undefined;
|
||||||
|
71c71
|
||||||
|
< var first_line2: Err!*const [21]u8 = ???;
|
||||||
|
---
|
||||||
|
> var first_line2: Err!*const [21]u8 = Err.Cthulhu;
|
||||||
|
79,80c79,80
|
||||||
|
< fn printSecondLine() ??? {
|
||||||
|
< var second_line2: ?*const [18]u8 = ???;
|
||||||
|
---
|
||||||
|
> fn printSecondLine() void {
|
||||||
|
> var second_line2: ?*const [18]u8 = null;
|
Loading…
Reference in a new issue