092_interfaces.zig 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. //
  2. // Remeber excerice xx with tagged unions. That was a lot more better
  3. // but it's can bee perfect.
  4. //
  5. // With tagged unions, it gets EVEN BETTER! If you don't have a
  6. // need for a separate enum, you can define an inferred enum with
  7. // your union all in one place. Just use the 'enum' keyword in
  8. // place of the tag type:
  9. //
  10. // const Foo = union(enum) {
  11. // small: u8,
  12. // medium: u32,
  13. // large: u64,
  14. // };
  15. //
  16. // Let's convert Insect. Doctor Zoraptera has already deleted the
  17. // explicit InsectStat enum for you!
  18. //
  19. const std = @import("std");
  20. const Ant = struct {
  21. still_alive: bool,
  22. pub fn print(self: Ant) void {
  23. std.debug.print("Ant is {s}.\n", .{if (self.still_alive) "alive" else "death"});
  24. }
  25. };
  26. const Bee = struct {
  27. flowers_visited: u16,
  28. pub fn print(self: Bee) void {
  29. std.debug.print("Bee visited {} flowers.\n", .{self.flowers_visited});
  30. }
  31. };
  32. const Grasshopper = struct {
  33. distance_hopped: u16,
  34. pub fn print(self: Grasshopper) void {
  35. std.debug.print("Grasshopper hopped {} m.\n", .{self.distance_hopped});
  36. }
  37. };
  38. const Insect = union(enum) {
  39. ant: Ant,
  40. bee: Bee,
  41. grasshopper: Grasshopper,
  42. pub fn print(self: Insect) void {
  43. switch (self) {
  44. inline else => |case| return case.print(),
  45. }
  46. }
  47. };
  48. pub fn main() !void {
  49. var my_insects = [_]Insect{ Insect{
  50. .ant = Ant{ .still_alive = true },
  51. }, Insect{
  52. .bee = Bee{ .flowers_visited = 17 },
  53. }, Insect{
  54. .grasshopper = Grasshopper{ .distance_hopped = 32 },
  55. } };
  56. try dailyReport(&my_insects);
  57. }
  58. fn dailyReport(insectReport: []Insect) !void {
  59. std.debug.print("Daily insect report:\n", .{});
  60. for (insectReport) |insect| {
  61. insect.print();
  62. }
  63. }
  64. // Inferred enums are neat, representing the tip of the iceberg
  65. // in the relationship between enums and unions. You can actually
  66. // coerce a union TO an enum (which gives you the active field
  67. // from the union as an enum). What's even wilder is that you can
  68. // coerce an enum to a union! But don't get too excited, that
  69. // only works when the union type is one of those weird zero-bit
  70. // types like void!
  71. //
  72. // Tagged unions, as with most ideas in computer science, have a
  73. // long history going back to the 1960s. However, they're only
  74. // recently becoming mainstream, particularly in system-level
  75. // programming languages. You might have also seen them called
  76. // "variants", "sum types", or even "enums"!