046_optionals2.zig 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. //
  2. // Now that we have optional types, we can apply them to structs.
  3. // The last time we checked in with our elephants, we had to link
  4. // all three of them together in a "circle" so that the last tail
  5. // linked to the first elephant. This is because we had NO CONCEPT
  6. // of a tail that didn't point to another elephant!
  7. //
  8. // We also introduce the handy ".?" shortcut:
  9. //
  10. // const foo = bar.?;
  11. //
  12. // is the same as
  13. //
  14. // const foo = bar orelse unreachable;
  15. //
  16. // See if you can find where we use this shortcut below.
  17. //
  18. // Now let's make those elephant tails optional!
  19. //
  20. const std = @import("std");
  21. const Elephant = struct {
  22. letter: u8,
  23. tail: *Elephant = null, // Hmm... tail needs something...
  24. visited: bool = false,
  25. };
  26. pub fn main() void {
  27. var elephantA = Elephant{ .letter = 'A' };
  28. var elephantB = Elephant{ .letter = 'B' };
  29. var elephantC = Elephant{ .letter = 'C' };
  30. // Link the elephants so that each tail "points" to the next.
  31. elephantA.tail = &elephantB;
  32. elephantB.tail = &elephantC;
  33. visitElephants(&elephantA);
  34. std.debug.print("\n", .{});
  35. }
  36. // This function visits all elephants once, starting with the
  37. // first elephant and following the tails to the next elephant.
  38. fn visitElephants(first_elephant: *Elephant) void {
  39. var e = first_elephant;
  40. while (!e.visited) {
  41. std.debug.print("Elephant {u}. ", .{e.letter});
  42. e.visited = true;
  43. // We should stop once we encounter a tail that
  44. // does NOT point to another element. What can
  45. // we put here to make that happen?
  46. e = e.tail ???
  47. }
  48. }