066_comptime.zig 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. //
  2. // "Compile time" is a program's environment while it is being
  3. // compiled. In contrast, "run time" is the environment while the
  4. // compiled program is executing (traditionally as machine code
  5. // on a hardware CPU).
  6. //
  7. // Errors make an easy example:
  8. //
  9. // 1. Compile-time error: caught by the compiler, usually
  10. // resulting in a message to the programmer.
  11. //
  12. // 2. Runtime error: either caught by the running program itself
  13. // or by the host hardware or operating system. Could be
  14. // gracefully caught and handled or could cause the computer
  15. // to crash (or halt and catch fire)!
  16. //
  17. // All compiled languages must perform a certain amount of logic
  18. // at compile time in order to analyze the code, maintain a table
  19. // of symbols (such as variable and function names), etc.
  20. //
  21. // Optimizing compilers can also figure out how much of a program
  22. // can be pre-computed or "inlined" at compile time to make the
  23. // resulting program more efficient. Smart compilers can even
  24. // "unroll" loops, turning their logic into a fast linear
  25. // sequence of statements (at the usually very slight expense of
  26. // the increased size of the repeated code).
  27. //
  28. // Zig takes these concepts further by making these optimizations
  29. // an integral part of the language itself!
  30. //
  31. const print = @import("std").debug.print;
  32. pub fn main() void {
  33. // ALL numeric literals in Zig are of type comptime_int or
  34. // comptime_float. They are of arbitrary size (as big or
  35. // little as you need).
  36. //
  37. // Notice how we don't have to specify a size like "u8",
  38. // "i32", or "f64" when we assign identifiers immutably with
  39. // "const".
  40. //
  41. // When we use these identifiers in our program, the VALUES
  42. // are inserted at compile time into the executable code. The
  43. // IDENTIFIERS "const_int" and "const_float" don't exist in
  44. // our compiled application!
  45. const const_int = 12345;
  46. const const_float = 987.654;
  47. print("Immutable: {}, {d:.3}; ", .{const_int, const_float});
  48. // But something changes when we assign the exact same values
  49. // to identifiers mutably with "var".
  50. //
  51. // The literals are STILL comptime_int and comptime_float,
  52. // but we wish to assign them to identifiers which are
  53. // mutable at runtime.
  54. //
  55. // To be mutable at runtime, these identifiers must refer to
  56. // areas of memory. In order to refer to areas of memory, Zig
  57. // must know exactly how much memory to reserve for these
  58. // values. Therefore, it follows that we just specify numeric
  59. // types with specific sizes. The comptime numbers will be
  60. // coerced (if they'll fit!) into your chosen runtime types.
  61. var var_int = 12345;
  62. var var_float = 987.654;
  63. // We can change what is stored at the areas set aside for
  64. // "var_int" and "var_float" in the running compiled program.
  65. var_int = 54321;
  66. var_float = 456.789;
  67. print("Mutable: {}, {d:.3}; ", .{var_int, var_float});
  68. // Bonus: Now that we're familiar with Zig's builtins, we can
  69. // also inspect the types to see what they are, no guessing
  70. // needed!
  71. print("Types: {}, {}, {}, {}\n", .{
  72. @TypeOf(const_int),
  73. @TypeOf(const_float),
  74. @TypeOf(var_int),
  75. @TypeOf(var_float),
  76. });
  77. }