Ex 065: improve hints, fix type printing change. For #120 and #128

This commit is contained in:
Dave Gauer 2022-08-29 18:30:38 -04:00
parent 4ce16782d0
commit 4eaef5fae4
2 changed files with 72 additions and 37 deletions

View file

@ -40,12 +40,12 @@
// (Notice how the two functions which return types start with // (Notice how the two functions which return types start with
// uppercase letters? This is a standard naming practice in Zig.) // uppercase letters? This is a standard naming practice in Zig.)
// //
const print = import(std).debug.print; // Oops! const print = @import("std").debug.print;
const Narcissus = struct { const Narcissus = struct {
me: *Narcissus = undefined, me: *Narcissus = undefined,
myself: *Narcissus = undefined, myself: *Narcissus = undefined,
echo: void = undefined, echo: void = undefined, // Alas, poor Echo!
fn fetchTheMostBeautifulType() type { fn fetchTheMostBeautifulType() type {
return @This(); return @This();
@ -57,20 +57,26 @@ pub fn main() void {
// Oops! We cannot leave the 'me' and 'myself' fields // Oops! We cannot leave the 'me' and 'myself' fields
// undefined. Please set them here: // undefined. Please set them here:
??? = &narcissus; narcissus.me = &narcissus;
??? = &narcissus; narcissus.??? = ???;
// This determines a "peer type" from three separate // This determines a "peer type" from three separate
// references (they just happen to all be the same object). // references (they just happen to all be the same object).
const T1 = @TypeOf(narcissus, narcissus.me.*, narcissus.myself.*); const Type1 = @TypeOf(narcissus, narcissus.me.*, narcissus.myself.*);
// Oh dear, we seem to have done something wrong when calling // Oh dear, we seem to have done something wrong when calling
// this function. It is namespaced to the struct, but doesn't // this function. We called it as a method, which would work
// use the method syntax (there's no self parameter). Please // if it had a self parameter. But it doesn't. (See above.)
// fix this call: //
const T2 = narcissus.fetchTheMostBeautifulType(); // The fix for this is very subtle, but it makes a big
// difference!
const Type2 = narcissus.fetchTheMostBeautifulType();
print("A {} loves all {}es. ", .{ T1, T2 }); // Now we print a pithy statement about Narcissus.
print("A {s} loves all {s}es. ", .{
maximumNarcissism(Type1),
maximumNarcissism(Type2),
});
// His final words as he was looking in // His final words as he was looking in
// those waters he habitually watched // those waters he habitually watched
@ -121,7 +127,23 @@ pub fn main() void {
// Alas, we can't use a regular 'for' loop here because // Alas, we can't use a regular 'for' loop here because
// 'fields' can only be evaluated at compile time. It seems // 'fields' can only be evaluated at compile time. It seems
// like we're overdue to learn about this "comptime" stuff, // like we're overdue to learn about this "comptime" stuff,
// doesn't it? :-) // doesn't it? Don't worry, we'll get there.
print(".\n", .{}); print(".\n", .{});
} }
// NOTE: This exercise did not originally include the function below.
// But a change after Zig 0.10.0 added the source file name to the
// type. "Narcissus" became "065_builtins2.Narcissus".
//
// To fix this, I've added this function to strip the filename from
// the front of the type name in the dumbest way possible. (It returns
// a slice of the type name starting at character 14 (assuming
// single-byte characters).
//
// We'll be seeing @typeName again in Exercise 070. For now, you can
// see that it takes a Type and returns a u8 "string".
fn maximumNarcissism(myType: anytype) []const u8 {
// Turn '065_builtins2.Narcissus' into 'Narcissus'
return @typeName(myType)[14..];
}

View file

@ -1,26 +1,39 @@
43c43 --- exercises/065_builtins2.zig
< const print = import(std).debug.print; // Oops! +++ answers/065_builtins2.zig
--- @@ -58,7 +58,7 @@
> const print = @import("std").debug.print; // Oops! We cannot leave the 'me' and 'myself' fields
60,61c60,61 // undefined. Please set them here:
< ??? = &narcissus; narcissus.me = &narcissus;
< ??? = &narcissus; - narcissus.??? = ???;
--- + narcissus.myself = &narcissus;
> narcissus.me = &narcissus;
> narcissus.myself = &narcissus; // This determines a "peer type" from three separate
71c71 // references (they just happen to all be the same object).
< const T2 = narcissus.fetchTheMostBeautifulType(); @@ -70,7 +70,7 @@
--- //
> const T2 = Narcissus.fetchTheMostBeautifulType(); // The fix for this is very subtle, but it makes a big
106c106 // difference!
< if (fields[0].??? != void) { - const Type2 = narcissus.fetchTheMostBeautifulType();
--- + const Type2 = Narcissus.fetchTheMostBeautifulType();
> if (fields[0].field_type != void) {
110c110 // Now we print a pithy statement about Narcissus.
< if (fields[1].??? != void) { print("A {s} loves all {s}es. ", .{
--- @@ -109,15 +109,15 @@
> if (fields[1].field_type != void) { // Please complete these 'if' statements so that the field
114c114 // name will not be printed if the field is of type 'void'
< if (fields[2].??? != void) { // (which is a zero-bit type that takes up no space at all!):
--- - if (fields[0].??? != void) {
> if (fields[2].field_type != void) { + if (fields[0].field_type != void) {
print(" {s}", .{@typeInfo(Narcissus).Struct.fields[0].name});
}
- if (fields[1].??? != void) {
+ if (fields[1].field_type != void) {
print(" {s}", .{@typeInfo(Narcissus).Struct.fields[1].name});
}
- if (fields[2].??? != void) {
+ if (fields[2].field_type != void) {
print(" {s}", .{@typeInfo(Narcissus).Struct.fields[2].name});
}