|
@@ -42,98 +42,98 @@
|
|
|
//
|
|
|
const print = @import("std").debug.print;
|
|
|
|
|
|
-const Narcissus = struct {
|
|
|
- me: *Narcissus = undefined,
|
|
|
- myself: *Narcissus = undefined,
|
|
|
- echo: void = undefined, // Alas, poor Echo!
|
|
|
-
|
|
|
- fn fetchTheMostBeautifulType() type {
|
|
|
- return @This();
|
|
|
- }
|
|
|
+const Narcissus = struct{
|
|
|
+ me: *Narcissus = undefined,
|
|
|
+ myself: *Narcissus = undefined,
|
|
|
+ echo: void = undefined, // Alas, poor Echo!
|
|
|
+
|
|
|
+ fn fetchTheMostBeautifulType() type{
|
|
|
+ return @This();
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
-pub fn main() void {
|
|
|
- var narcissus: Narcissus = Narcissus{};
|
|
|
-
|
|
|
- // Oops! We cannot leave the 'me' and 'myself' fields
|
|
|
- // undefined. Please set them here:
|
|
|
- narcissus.me = &narcissus;
|
|
|
- narcissus.??? = ???;
|
|
|
-
|
|
|
- // This determines a "peer type" from three separate
|
|
|
- // references (they just happen to all be the same object).
|
|
|
- const Type1 = @TypeOf(narcissus, narcissus.me.*, narcissus.myself.*);
|
|
|
-
|
|
|
- // Oh dear, we seem to have done something wrong when calling
|
|
|
- // this function. We called it as a method, which would work
|
|
|
- // if it had a self parameter. But it doesn't. (See above.)
|
|
|
- //
|
|
|
- // The fix for this is very subtle, but it makes a big
|
|
|
- // difference!
|
|
|
- const Type2 = narcissus.fetchTheMostBeautifulType();
|
|
|
-
|
|
|
- // 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
|
|
|
- // those waters he habitually watched
|
|
|
- // were these:
|
|
|
- // "Alas, my beloved boy, in vain!"
|
|
|
- // The place gave every word back in reply.
|
|
|
- // He cried:
|
|
|
- // "Farewell."
|
|
|
- // And Echo called:
|
|
|
- // "Farewell!"
|
|
|
- //
|
|
|
- // --Ovid, The Metamorphoses
|
|
|
- // translated by Ian Johnston
|
|
|
-
|
|
|
- print("He has room in his heart for:", .{});
|
|
|
-
|
|
|
- // A StructFields array
|
|
|
- const fields = @typeInfo(Narcissus).@"struct".fields;
|
|
|
-
|
|
|
- // 'fields' is a slice of StructFields. Here's the declaration:
|
|
|
- //
|
|
|
- // pub const StructField = struct {
|
|
|
- // name: [:0]const u8,
|
|
|
- // type: type,
|
|
|
- // default_value_ptr: ?*const anyopaque,
|
|
|
- // is_comptime: bool,
|
|
|
- // alignment: comptime_int,
|
|
|
- //
|
|
|
- // defaultValue() ?sf.type // Function that loads the
|
|
|
- // // field's default value from
|
|
|
- // // `default_value_ptr`
|
|
|
- // };
|
|
|
- //
|
|
|
- // Please complete these 'if' statements so that the field
|
|
|
- // name will not be printed if the field is of type 'void'
|
|
|
- // (which is a zero-bit type that takes up no space at all!):
|
|
|
- if (fields[0].??? != void) {
|
|
|
- print(" {s}", .{fields[0].name});
|
|
|
- }
|
|
|
-
|
|
|
- if (fields[1].??? != void) {
|
|
|
- print(" {s}", .{fields[1].name});
|
|
|
- }
|
|
|
-
|
|
|
- if (fields[2].??? != void) {
|
|
|
- print(" {s}", .{fields[2].name});
|
|
|
- }
|
|
|
-
|
|
|
- // Yuck, look at all that repeated code above! I don't know
|
|
|
- // about you, but it makes me itchy.
|
|
|
- //
|
|
|
- // Alas, we can't use a regular 'for' loop here because
|
|
|
- // 'fields' can only be evaluated at compile time. It seems
|
|
|
- // like we're overdue to learn about this "comptime" stuff,
|
|
|
- // doesn't it? Don't worry, we'll get there.
|
|
|
-
|
|
|
- print(".\n", .{});
|
|
|
+pub fn main() void{
|
|
|
+ var narcissus: Narcissus = Narcissus{};
|
|
|
+
|
|
|
+ // Oops! We cannot leave the 'me' and 'myself' fields
|
|
|
+ // undefined. Please set them here:
|
|
|
+ narcissus.me = &narcissus;
|
|
|
+ narcissus.myself = &narcissus;
|
|
|
+
|
|
|
+ // This determines a "peer type" from three separate
|
|
|
+ // references (they just happen to all be the same object).
|
|
|
+ const Type1 = @TypeOf(narcissus, narcissus.me.*, narcissus.myself.*);
|
|
|
+
|
|
|
+ // Oh dear, we seem to have done something wrong when calling
|
|
|
+ // this function. We called it as a method, which would work
|
|
|
+ // if it had a self parameter. But it doesn't. (See above.)
|
|
|
+ //
|
|
|
+ // The fix for this is very subtle, but it makes a big
|
|
|
+ // difference!
|
|
|
+ const Type2 = Narcissus.fetchTheMostBeautifulType();
|
|
|
+
|
|
|
+ // 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
|
|
|
+ // those waters he habitually watched
|
|
|
+ // were these:
|
|
|
+ // "Alas, my beloved boy, in vain!"
|
|
|
+ // The place gave every word back in reply.
|
|
|
+ // He cried:
|
|
|
+ // "Farewell."
|
|
|
+ // And Echo called:
|
|
|
+ // "Farewell!"
|
|
|
+ //
|
|
|
+ // --Ovid, The Metamorphoses
|
|
|
+ // translated by Ian Johnston
|
|
|
+
|
|
|
+ print("He has room in his heart for:", .{});
|
|
|
+
|
|
|
+ // A StructFields array
|
|
|
+ const fields = @typeInfo(Narcissus).@"struct".fields;
|
|
|
+
|
|
|
+ // 'fields' is a slice of StructFields. Here's the declaration:
|
|
|
+ //
|
|
|
+ // pub const StructField = struct{
|
|
|
+ // name: [:0]const u8,
|
|
|
+ // type: type,
|
|
|
+ // default_value_ptr: ?*const anyopaque,
|
|
|
+ // is_comptime: bool,
|
|
|
+ // alignment: comptime_int,
|
|
|
+ //
|
|
|
+ // defaultValue() ?sf.type // Function that loads the
|
|
|
+ // // field's default value from
|
|
|
+ // // `default_value_ptr`
|
|
|
+ // };
|
|
|
+ //
|
|
|
+ // Please complete these 'if' statements so that the field
|
|
|
+ // name will not be printed if the field is of type 'void'
|
|
|
+ // (which is a zero-bit type that takes up no space at all!):
|
|
|
+ if(fields[0].type != void){
|
|
|
+ print(" {s}", .{fields[0].name});
|
|
|
+ }
|
|
|
+
|
|
|
+ if(fields[1].type != void){
|
|
|
+ print(" {s}", .{fields[1].name});
|
|
|
+ }
|
|
|
+
|
|
|
+ if(fields[2].type != void){
|
|
|
+ print(" {s}", .{fields[2].name});
|
|
|
+ }
|
|
|
+
|
|
|
+ // Yuck, look at all that repeated code above! I don't know
|
|
|
+ // about you, but it makes me itchy.
|
|
|
+ //
|
|
|
+ // Alas, we can't use a regular 'for' loop here because
|
|
|
+ // 'fields' can only be evaluated at compile time. It seems
|
|
|
+ // like we're overdue to learn about this "comptime" stuff,
|
|
|
+ // doesn't it? Don't worry, we'll get there.
|
|
|
+
|
|
|
+ print(".\n", .{});
|
|
|
}
|
|
|
|
|
|
// NOTE: This exercise did not originally include the function below.
|
|
@@ -146,10 +146,11 @@ pub fn main() void {
|
|
|
//
|
|
|
// 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 {
|
|
|
- const indexOf = @import("std").mem.indexOf;
|
|
|
-
|
|
|
- // Turn "065_builtins2.Narcissus" into "Narcissus"
|
|
|
- const name = @typeName(myType);
|
|
|
- return name[indexOf(u8, name, ".").? + 1 ..];
|
|
|
+fn maximumNarcissism(myType: anytype) []const u8{
|
|
|
+ const indexOf = @import("std").mem.indexOf;
|
|
|
+
|
|
|
+ // Turn "065_builtins2.Narcissus" into "Narcissus"
|
|
|
+ const name = @typeName(myType);
|
|
|
+ return name[indexOf(u8, name, ".").? + 1 ..];
|
|
|
}
|
|
|
+
|