| ... | ... | @@ -108,7 +108,7 @@ |
| 108 | 108 | {#code_begin|exe|hello#} |
| 109 | 109 | const std = @import("std"); |
| 110 | 110 | |
| 111 | | pub fn main() %void { |
| 111 | pub fn main() !void { |
| 112 | 112 | // If this program is run without stdout attached, exit with an error. |
| 113 | 113 | var stdout_file = try std.io.getStdOut(); |
| 114 | 114 | // If this program encounters pipe failure when printing to stdout, exit |
| ... | ... | @@ -129,8 +129,8 @@ pub fn main() void { |
| 129 | 129 | } |
| 130 | 130 | {#code_end#} |
| 131 | 131 | <p> |
| 132 | | Note that we also left off the <code class="zig">%</code> from the return type. |
| 133 | | In Zig, if your main function cannot fail, you may use the <code class="zig">void</code> return type. |
| 132 | Note that we also left off the <code class="zig">!</code> from the return type. |
| 133 | In Zig, if your main function cannot fail, you must use the <code class="zig">void</code> return type. |
| 134 | 134 | </p> |
| 135 | 135 | {#see_also|Values|@import|Errors|Root Source File#} |
| 136 | 136 | {#header_close#} |
| ... | ... | @@ -151,10 +151,7 @@ const warn = std.debug.warn; |
| 151 | 151 | const os = std.os; |
| 152 | 152 | const assert = std.debug.assert; |
| 153 | 153 | |
| 154 | | // error declaration, makes `error.ArgNotFound` available |
| 155 | | error ArgNotFound; |
| 156 | | |
| 157 | | pub fn main() %void { |
| 154 | pub fn main() void { |
| 158 | 155 | // integers |
| 159 | 156 | const one_plus_one: i32 = 1 + 1; |
| 160 | 157 | warn("1 + 1 = {}\n", one_plus_one); |
| ... | ... | @@ -183,7 +180,7 @@ pub fn main() %void { |
| 183 | 180 | @typeName(@typeOf(nullable_value)), nullable_value); |
| 184 | 181 | |
| 185 | 182 | // error union |
| 186 | | var number_or_error: %i32 = error.ArgNotFound; |
| 183 | var number_or_error: error!i32 = error.ArgNotFound; |
| 187 | 184 | |
| 188 | 185 | warn("\nerror union 1\ntype: {}\nvalue: {}\n", |
| 189 | 186 | @typeName(@typeOf(number_or_error)), number_or_error); |
| ... | ... | @@ -691,7 +688,7 @@ const warn = @import("std").debug.warn; |
| 691 | 688 | extern fn foo_strict(x: f64) f64; |
| 692 | 689 | extern fn foo_optimized(x: f64) f64; |
| 693 | 690 | |
| 694 | | pub fn main() %void { |
| 691 | pub fn main() void { |
| 695 | 692 | const x = 0.001; |
| 696 | 693 | warn("optimized = {}\n", foo_optimized(x)); |
| 697 | 694 | warn("strict = {}\n", foo_strict(x)); |
| ... | ... | @@ -1046,7 +1043,7 @@ a catch |err| b</code></pre></td> |
| 1046 | 1043 | <code>err</code> is the <code>error</code> and is in scope of the expression <code>b</code>. |
| 1047 | 1044 | </td> |
| 1048 | 1045 | <td> |
| 1049 | | <pre><code class="zig">const value: %u32 = null; |
| 1046 | <pre><code class="zig">const value: error!u32 = error.Broken; |
| 1050 | 1047 | const unwrapped = value catch 1234; |
| 1051 | 1048 | unwrapped == 1234</code></pre> |
| 1052 | 1049 | </td> |
| ... | ... | @@ -1279,7 +1276,8 @@ const ptr = &amp;x; |
| 1279 | 1276 | {#header_close#} |
| 1280 | 1277 | {#header_open|Precedence#} |
| 1281 | 1278 | <pre><code>x() x[] x.y |
| 1282 | | !x -x -%x ~x *x &amp;x ?x %x ??x |
| 1279 | a!b |
| 1280 | !x -x -%x ~x *x &amp;x ?x ??x |
| 1283 | 1281 | x{} |
| 1284 | 1282 | ! * / % ** *% |
| 1285 | 1283 | + - ++ +% -% |
| ... | ... | @@ -2278,8 +2276,8 @@ fn eventuallyNullSequence() ?u32 { |
| 2278 | 2276 | break :blk numbers_left; |
| 2279 | 2277 | }; |
| 2280 | 2278 | } |
| 2281 | | error ReachedZero; |
| 2282 | | fn eventuallyErrorSequence() %u32 { |
| 2279 | |
| 2280 | fn eventuallyErrorSequence() error!u32 { |
| 2283 | 2281 | return if (numbers_left == 0) error.ReachedZero else blk: { |
| 2284 | 2282 | numbers_left -= 1; |
| 2285 | 2283 | break :blk numbers_left; |
| ... | ... | @@ -2408,7 +2406,7 @@ fn typeNameLength(comptime T: type) usize { |
| 2408 | 2406 | // If expressions have three uses, corresponding to the three types: |
| 2409 | 2407 | // * bool |
| 2410 | 2408 | // * ?T |
| 2411 | | // * %T |
| 2409 | // * error!T |
| 2412 | 2410 | |
| 2413 | 2411 | const assert = @import("std").debug.assert; |
| 2414 | 2412 | |
| ... | ... | @@ -2469,20 +2467,18 @@ test "if nullable" { |
| 2469 | 2467 | } |
| 2470 | 2468 | } |
| 2471 | 2469 | |
| 2472 | | error BadValue; |
| 2473 | | error LessBadValue; |
| 2474 | 2470 | test "if error union" { |
| 2475 | 2471 | // If expressions test for errors. |
| 2476 | 2472 | // Note the |err| capture on the else. |
| 2477 | 2473 | |
| 2478 | | const a: %u32 = 0; |
| 2474 | const a: error!u32 = 0; |
| 2479 | 2475 | if (a) |value| { |
| 2480 | 2476 | assert(value == 0); |
| 2481 | 2477 | } else |err| { |
| 2482 | 2478 | unreachable; |
| 2483 | 2479 | } |
| 2484 | 2480 | |
| 2485 | | const b: %u32 = error.BadValue; |
| 2481 | const b: error!u32 = error.BadValue; |
| 2486 | 2482 | if (b) |value| { |
| 2487 | 2483 | unreachable; |
| 2488 | 2484 | } else |err| { |
| ... | ... | @@ -2500,7 +2496,7 @@ test "if error union" { |
| 2500 | 2496 | } |
| 2501 | 2497 | |
| 2502 | 2498 | // Access the value by reference using a pointer capture. |
| 2503 | | var c: %u32 = 3; |
| 2499 | var c: error!u32 = 3; |
| 2504 | 2500 | if (c) |*value| { |
| 2505 | 2501 | *value = 9; |
| 2506 | 2502 | } else |err| { |
| ... | ... | @@ -2568,8 +2564,7 @@ test "defer unwinding" { |
| 2568 | 2564 | // |
| 2569 | 2565 | // This is especially useful in allowing a function to clean up properly |
| 2570 | 2566 | // on error, and replaces goto error handling tactics as seen in c. |
| 2571 | | error DeferError; |
| 2572 | | fn deferErrorExample(is_error: bool) %void { |
| 2567 | fn deferErrorExample(is_error: bool) !void { |
| 2573 | 2568 | warn("\nstart of function\n"); |
| 2574 | 2569 | |
| 2575 | 2570 | // This will always be executed on exit |
| ... | ... | @@ -2678,7 +2673,7 @@ test "foo" { |
| 2678 | 2673 | assert(value == 1234); |
| 2679 | 2674 | } |
| 2680 | 2675 | |
| 2681 | | fn bar() %u32 { |
| 2676 | fn bar() error!u32 { |
| 2682 | 2677 | return 1234; |
| 2683 | 2678 | } |
| 2684 | 2679 | |
| ... | ... | @@ -2791,13 +2786,8 @@ test "implicitly cast to const pointer" { |
| 2791 | 2786 | One of the distinguishing features of Zig is its exception handling strategy. |
| 2792 | 2787 | </p> |
| 2793 | 2788 | <p> |
| 2794 | | Among the top level declarations available is the error value declaration: |
| 2789 | TODO rewrite the errors section to take into account error sets |
| 2795 | 2790 | </p> |
| 2796 | | {#code_begin|syntax#} |
| 2797 | | error FileNotFound; |
| 2798 | | error OutOfMemory; |
| 2799 | | error UnexpectedToken; |
| 2800 | | {#code_end#} |
| 2801 | 2791 | <p> |
| 2802 | 2792 | These error values are assigned an unsigned integer value greater than 0 at |
| 2803 | 2793 | compile time. You are allowed to declare the same error value more than once, |
| ... | ... | @@ -2809,26 +2799,23 @@ error UnexpectedToken; |
| 2809 | 2799 | </p> |
| 2810 | 2800 | <p> |
| 2811 | 2801 | Each error value across the entire compilation unit gets a unique integer, |
| 2812 | | and this determines the size of the pure error type. |
| 2802 | and this determines the size of the error set type. |
| 2813 | 2803 | </p> |
| 2814 | 2804 | <p> |
| 2815 | | The pure error type is one of the error values, and in the same way that pointers |
| 2816 | | cannot be null, a pure error is always an error. |
| 2805 | The error set type is one of the error values, and in the same way that pointers |
| 2806 | cannot be null, a error set instance is always an error. |
| 2817 | 2807 | </p> |
| 2818 | 2808 | {#code_begin|syntax#}const pure_error = error.FileNotFound;{#code_end#} |
| 2819 | 2809 | <p> |
| 2820 | | Most of the time you will not find yourself using a pure error type. Instead, |
| 2821 | | likely you will be using the error union type. This is when you take a normal type, |
| 2822 | | and prefix it with the <code>%</code> operator. |
| 2810 | Most of the time you will not find yourself using an error set type. Instead, |
| 2811 | likely you will be using the error union type. This is when you take an error set |
| 2812 | and a normal type, and create an error union with the <code>!</code> binary operator. |
| 2823 | 2813 | </p> |
| 2824 | 2814 | <p> |
| 2825 | 2815 | Here is a function to parse a string into a 64-bit integer: |
| 2826 | 2816 | </p> |
| 2827 | 2817 | {#code_begin|test#} |
| 2828 | | error InvalidChar; |
| 2829 | | error Overflow; |
| 2830 | | |
| 2831 | | pub fn parseU64(buf: []const u8, radix: u8) %u64 { |
| 2818 | pub fn parseU64(buf: []const u8, radix: u8) !u64 { |
| 2832 | 2819 | var x: u64 = 0; |
| 2833 | 2820 | |
| 2834 | 2821 | for (buf) |c| { |
| ... | ... | @@ -2867,13 +2854,14 @@ test "parse u64" { |
| 2867 | 2854 | } |
| 2868 | 2855 | {#code_end#} |
| 2869 | 2856 | <p> |
| 2870 | | Notice the return type is <code>%u64</code>. This means that the function |
| 2871 | | either returns an unsigned 64 bit integer, or an error. |
| 2857 | Notice the return type is <code>!u64</code>. This means that the function |
| 2858 | either returns an unsigned 64 bit integer, or an error. We left off the error set |
| 2859 | to the left of the <code>!</code>, so the error set is inferred. |
| 2872 | 2860 | </p> |
| 2873 | 2861 | <p> |
| 2874 | 2862 | Within the function definition, you can see some return statements that return |
| 2875 | | a pure error, and at the bottom a return statement that returns a <code>u64</code>. |
| 2876 | | Both types implicitly cast to <code>%u64</code>. |
| 2863 | an error, and at the bottom a return statement that returns a <code>u64</code>. |
| 2864 | Both types implicitly cast to <code>error!u64</code>. |
| 2877 | 2865 | </p> |
| 2878 | 2866 | <p> |
| 2879 | 2867 | What it looks like to use this function varies depending on what you're |
| ... | ... | @@ -2900,7 +2888,7 @@ fn doAThing(str: []u8) void { |
| 2900 | 2888 | <p>Let's say you wanted to return the error if you got one, otherwise continue with the |
| 2901 | 2889 | function logic:</p> |
| 2902 | 2890 | {#code_begin|syntax#} |
| 2903 | | fn doAThing(str: []u8) %void { |
| 2891 | fn doAThing(str: []u8) !void { |
| 2904 | 2892 | const number = parseU64(str, 10) catch |err| return err; |
| 2905 | 2893 | // ... |
| 2906 | 2894 | } |
| ... | ... | @@ -2909,7 +2897,7 @@ fn doAThing(str: []u8) %void { |
| 2909 | 2897 | There is a shortcut for this. The <code>try</code> expression: |
| 2910 | 2898 | </p> |
| 2911 | 2899 | {#code_begin|syntax#} |
| 2912 | | fn doAThing(str: []u8) %void { |
| 2900 | fn doAThing(str: []u8) !void { |
| 2913 | 2901 | const number = try parseU64(str, 10); |
| 2914 | 2902 | // ... |
| 2915 | 2903 | } |
| ... | ... | @@ -2959,7 +2947,7 @@ fn doAThing(str: []u8) void { |
| 2959 | 2947 | Example: |
| 2960 | 2948 | </p> |
| 2961 | 2949 | {#code_begin|syntax#} |
| 2962 | | fn createFoo(param: i32) %Foo { |
| 2950 | fn createFoo(param: i32) !Foo { |
| 2963 | 2951 | const foo = try tryToAllocateFoo(); |
| 2964 | 2952 | // now we have allocated foo. we need to free it if the function fails. |
| 2965 | 2953 | // but we want to return it if the function succeeds. |
| ... | ... | @@ -3567,7 +3555,7 @@ pub fn main() void { |
| 3567 | 3555 | |
| 3568 | 3556 | {#code_begin|syntax#} |
| 3569 | 3557 | /// Calls print and then flushes the buffer. |
| 3570 | | pub fn printf(self: &OutStream, comptime format: []const u8, args: ...) %void { |
| 3558 | pub fn printf(self: &OutStream, comptime format: []const u8, args: ...) error!void { |
| 3571 | 3559 | const State = enum { |
| 3572 | 3560 | Start, |
| 3573 | 3561 | OpenBrace, |
| ... | ... | @@ -3639,7 +3627,7 @@ pub fn printf(self: &OutStream, comptime format: []const u8, args: ...) %void { |
| 3639 | 3627 | and emits a function that actually looks like this: |
| 3640 | 3628 | </p> |
| 3641 | 3629 | {#code_begin|syntax#} |
| 3642 | | pub fn printf(self: &OutStream, arg0: i32, arg1: []const u8) %void { |
| 3630 | pub fn printf(self: &OutStream, arg0: i32, arg1: []const u8) !void { |
| 3643 | 3631 | try self.write("here is a string: '"); |
| 3644 | 3632 | try self.printValue(arg0); |
| 3645 | 3633 | try self.write("' here is a number: "); |
| ... | ... | @@ -3653,7 +3641,7 @@ pub fn printf(self: &OutStream, arg0: i32, arg1: []const u8) %void { |
| 3653 | 3641 | on the type: |
| 3654 | 3642 | </p> |
| 3655 | 3643 | {#code_begin|syntax#} |
| 3656 | | pub fn printValue(self: &OutStream, value: var) %void { |
| 3644 | pub fn printValue(self: &OutStream, value: var) !void { |
| 3657 | 3645 | const T = @typeOf(value); |
| 3658 | 3646 | if (@isInteger(T)) { |
| 3659 | 3647 | return self.printInt(T, value); |
| ... | ... | @@ -4582,7 +4570,7 @@ pub const TypeId = enum { |
| 4582 | 4570 | {#code_begin|syntax#} |
| 4583 | 4571 | const Builder = @import("std").build.Builder; |
| 4584 | 4572 | |
| 4585 | | pub fn build(b: &Builder) %void { |
| 4573 | pub fn build(b: &Builder) void { |
| 4586 | 4574 | const exe = b.addExecutable("example", "example.zig"); |
| 4587 | 4575 | exe.setBuildMode(b.standardReleaseOptions()); |
| 4588 | 4576 | b.default_step.dependOn(&exe.step); |
| ... | ... | @@ -4724,7 +4712,7 @@ comptime { |
| 4724 | 4712 | {#code_begin|exe_err#} |
| 4725 | 4713 | const math = @import("std").math; |
| 4726 | 4714 | const warn = @import("std").debug.warn; |
| 4727 | | pub fn main() %void { |
| 4715 | pub fn main() !void { |
| 4728 | 4716 | var byte: u8 = 255; |
| 4729 | 4717 | |
| 4730 | 4718 | byte = if (math.add(u8, byte, 1)) |result| result else |err| { |
| ... | ... | @@ -4752,7 +4740,7 @@ pub fn main() %void { |
| 4752 | 4740 | </p> |
| 4753 | 4741 | {#code_begin|exe#} |
| 4754 | 4742 | const warn = @import("std").debug.warn; |
| 4755 | | pub fn main() %void { |
| 4743 | pub fn main() void { |
| 4756 | 4744 | var byte: u8 = 255; |
| 4757 | 4745 | |
| 4758 | 4746 | var result: u8 = undefined; |
| ... | ... | @@ -4861,14 +4849,12 @@ pub fn main() void { |
| 4861 | 4849 | {#header_close#} |
| 4862 | 4850 | {#header_open|Attempt to Unwrap Error#} |
| 4863 | 4851 | <p>At compile-time:</p> |
| 4864 | | {#code_begin|test_err|unable to unwrap error 'UnableToReturnNumber'#} |
| 4852 | {#code_begin|test_err|caught unexpected error 'UnableToReturnNumber'#} |
| 4865 | 4853 | comptime { |
| 4866 | 4854 | const number = getNumberOrFail() catch unreachable; |
| 4867 | 4855 | } |
| 4868 | 4856 | |
| 4869 | | error UnableToReturnNumber; |
| 4870 | | |
| 4871 | | fn getNumberOrFail() %i32 { |
| 4857 | fn getNumberOrFail() !i32 { |
| 4872 | 4858 | return error.UnableToReturnNumber; |
| 4873 | 4859 | } |
| 4874 | 4860 | {#code_end#} |
| ... | ... | @@ -4888,9 +4874,7 @@ pub fn main() void { |
| 4888 | 4874 | } |
| 4889 | 4875 | } |
| 4890 | 4876 | |
| 4891 | | error UnableToReturnNumber; |
| 4892 | | |
| 4893 | | fn getNumberOrFail() %i32 { |
| 4877 | fn getNumberOrFail() !i32 { |
| 4894 | 4878 | return error.UnableToReturnNumber; |
| 4895 | 4879 | } |
| 4896 | 4880 | {#code_end#} |
| ... | ... | @@ -4898,7 +4882,6 @@ fn getNumberOrFail() %i32 { |
| 4898 | 4882 | {#header_open|Invalid Error Code#} |
| 4899 | 4883 | <p>At compile-time:</p> |
| 4900 | 4884 | {#code_begin|test_err|integer value 11 represents no error#} |
| 4901 | | error AnError; |
| 4902 | 4885 | comptime { |
| 4903 | 4886 | const err = error.AnError; |
| 4904 | 4887 | const number = u32(err) + 10; |
| ... | ... | @@ -5298,7 +5281,7 @@ int main(int argc, char **argv) { |
| 5298 | 5281 | {#code_begin|syntax#} |
| 5299 | 5282 | const Builder = @import("std").build.Builder; |
| 5300 | 5283 | |
| 5301 | | pub fn build(b: &Builder) %void { |
| 5284 | pub fn build(b: &Builder) void { |
| 5302 | 5285 | const obj = b.addObject("base64", "base64.zig"); |
| 5303 | 5286 | |
| 5304 | 5287 | const exe = b.addCExecutable("test"); |