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. 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. 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. expect(value == 0);
  30. } else {
  31. unreachable;
  32. }
  33. const b: ?u32 = null;
  34. if (b) |value| {
  35. unreachable;
  36. } else {
  37. expect(true);
  38. }
  39. // The else is not required.
  40. if (a) |value| {
  41. expect(value == 0);
  42. }
  43. // To test against null only, use the binary equality operator.
  44. if (b == null) {
  45. 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. 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. expect(value == 0);
  64. } else |err| {
  65. unreachable;
  66. }
  67. const b: anyerror!u32 = error.BadValue;
  68. if (b) |value| {
  69. unreachable;
  70. } else |err| {
  71. expect(err == error.BadValue);
  72. }
  73. // The else and |err| capture is strictly required.
  74. if (a) |value| {
  75. expect(value == 0);
  76. } else |_| {}
  77. // To check only the error value, use an empty block expression.
  78. if (b) |_| {} else |err| {
  79. expect(err == error.BadValue);
  80. }
  81. // Access the value by reference using a pointer capture.
  82. var c: anyerror!u32 = 3;
  83. if (c) |*value| {
  84. value.* = 9;
  85. } else |err| {
  86. unreachable;
  87. }
  88. if (c) |value| {
  89. expect(value == 9);
  90. } else |err| {
  91. unreachable;
  92. }
  93. }
  94. test "if error union with optional" {
  95. // If expressions test for errors before unwrapping optionals.
  96. // The |optional_value| capture's type is ?u32.
  97. const a: anyerror!?u32 = 0;
  98. if (a) |optional_value| {
  99. expect(optional_value.? == 0);
  100. } else |err| {
  101. unreachable;
  102. }
  103. const b: anyerror!?u32 = null;
  104. if (b) |optional_value| {
  105. expect(optional_value == null);
  106. } else |err| {
  107. unreachable;
  108. }
  109. const c: anyerror!?u32 = error.BadValue;
  110. if (c) |optional_value| {
  111. unreachable;
  112. } else |err| {
  113. expect(err == error.BadValue);
  114. }
  115. // Access the value by reference by using a pointer capture each time.
  116. var d: anyerror!?u32 = 3;
  117. if (d) |*optional_value| {
  118. if (optional_value.*) |*value| {
  119. value.* = 9;
  120. }
  121. } else |err| {
  122. unreachable;
  123. }
  124. if (d) |optional_value| {
  125. expect(optional_value.? == 9);
  126. } else |err| {
  127. unreachable;
  128. }
  129. }
  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: