if

if.zig

  1. // If expressions have three uses, corresponding to the three types:
  2. // * bool
  3. // * ?T
  4. // * anyerror!T
  5. const expect = @import("std").testing.expect;
  6. test "if expression" {
  7. // If expressions are used instead of a ternary expression.
  8. const a: u32 = 5;
  9. const b: u32 = 4;
  10. const result = if (a != b) 47 else 3089;
  11. try expect(result == 47);
  12. }
  13. test "if boolean" {
  14. // If expressions test boolean conditions.
  15. const a: u32 = 5;
  16. const b: u32 = 4;
  17. if (a != b) {
  18. try expect(true);
  19. } else if (a == 9) {
  20. unreachable;
  21. } else {
  22. unreachable;
  23. }
  24. }
  25. test "if optional" {
  26. // If expressions test for null.
  27. const a: ?u32 = 0;
  28. if (a) |value| {
  29. try expect(value == 0);
  30. } else {
  31. unreachable;
  32. }
  33. const b: ?u32 = null;
  34. if (b) |_| {
  35. unreachable;
  36. } else {
  37. try expect(true);
  38. }
  39. // The else is not required.
  40. if (a) |value| {
  41. try expect(value == 0);
  42. }
  43. // To test against null only, use the binary equality operator.
  44. if (b == null) {
  45. try expect(true);
  46. }
  47. // Access the value by reference using a pointer capture.
  48. var c: ?u32 = 3;
  49. if (c) |*value| {
  50. value.* = 2;
  51. }
  52. if (c) |value| {
  53. try expect(value == 2);
  54. } else {
  55. unreachable;
  56. }
  57. }
  58. test "if error union" {
  59. // If expressions test for errors.
  60. // Note the |err| capture on the else.
  61. const a: anyerror!u32 = 0;
  62. if (a) |value| {
  63. try expect(value == 0);
  64. } else |err| {
  65. _ = err;
  66. unreachable;
  67. }
  68. const b: anyerror!u32 = error.BadValue;
  69. if (b) |value| {
  70. _ = value;
  71. unreachable;
  72. } else |err| {
  73. try expect(err == error.BadValue);
  74. }
  75. // The else and |err| capture is strictly required.
  76. if (a) |value| {
  77. try expect(value == 0);
  78. } else |_| {}
  79. // To check only the error value, use an empty block expression.
  80. if (b) |_| {} else |err| {
  81. try expect(err == error.BadValue);
  82. }
  83. // Access the value by reference using a pointer capture.
  84. var c: anyerror!u32 = 3;
  85. if (c) |*value| {
  86. value.* = 9;
  87. } else |_| {
  88. unreachable;
  89. }
  90. if (c) |value| {
  91. try expect(value == 9);
  92. } else |_| {
  93. unreachable;
  94. }
  95. }
  96. test "if error union with optional" {
  97. // If expressions test for errors before unwrapping optionals.
  98. // The |optional_value| capture's type is ?u32.
  99. const a: anyerror!?u32 = 0;
  100. if (a) |optional_value| {
  101. try expect(optional_value.? == 0);
  102. } else |err| {
  103. _ = err;
  104. unreachable;
  105. }
  106. const b: anyerror!?u32 = null;
  107. if (b) |optional_value| {
  108. try expect(optional_value == null);
  109. } else |_| {
  110. unreachable;
  111. }
  112. const c: anyerror!?u32 = error.BadValue;
  113. if (c) |optional_value| {
  114. _ = optional_value;
  115. unreachable;
  116. } else |err| {
  117. try expect(err == error.BadValue);
  118. }
  119. // Access the value by reference by using a pointer capture each time.
  120. var d: anyerror!?u32 = 3;
  121. if (d) |*optional_value| {
  122. if (optional_value.*) |*value| {
  123. value.* = 9;
  124. }
  125. } else |_| {
  126. unreachable;
  127. }
  128. if (d) |optional_value| {
  129. try expect(optional_value.? == 9);
  130. } else |_| {
  131. unreachable;
  132. }
  133. }

Shell

  1. $ zig test if.zig
  2. 1/5 test "if expression"... OK
  3. 2/5 test "if boolean"... OK
  4. 3/5 test "if optional"... OK
  5. 4/5 test "if error union"... OK
  6. 5/5 test "if error union with optional"... OK
  7. All 5 tests passed.

See also: