### Zig Switch Continue Example Source: https://ziglang.org/documentation/0.16.0 Demonstrates the use of `continue :sw` to jump to a specific prong in a labeled switch statement. This example shows how `continue` can be used with different values and how `break :sw` can exit the switch. ```zig const std = @import("std"); test "switch continue" { sw: switch (@as(i32, 5)) { 5 => continue :sw 4, // `continue` can occur multiple times within a single switch prong. 2...4 => |v| { if (v > 3) { continue :sw 2; } else if (v == 3) { // `break` can target labeled loops. break :sw; } continue :sw 1; }, 1 => return, else => unreachable, } } ``` -------------------------------- ### Build and Run Mixed Object File Example Source: https://ziglang.org/documentation/0.16.0 Commands to build the project with mixed Zig and C object files and then run the resulting executable. ```shell $ `zig build` $ `./zig-out/bin/test` all your base are belong to us ``` -------------------------------- ### Compile and Run C Import Example Source: https://ziglang.org/documentation/0.16.0 Shows the shell commands to compile a Zig file that imports C headers and then execute the compiled program. ```shell $ `zig build-exe cImport_builtin.zig -lc` $ `./cImport_builtin` hello ``` -------------------------------- ### Global Assembly Example in Zig Source: https://ziglang.org/documentation/0.16.0 Demonstrates global assembly in Zig, where assembly code is unconditionally included and concatenated verbatim. This example defines a function `my_func` using x86_64 assembly. ```zig const std = @import("std"); const expectEqual = std.testing.expectEqual; comptime { asm ( \.global my_func; \.type my_func, @function; \my_func: \ lea (%rdi,%rsi,1),%eax \ retq ); } extern fn my_func(a: i32, b: i32) i32; test "global assembly" { try expectEqual(46, my_func(12, 34)); } ``` -------------------------------- ### Example build.zig for standard build options Source: https://ziglang.org/documentation/0.16.0 This snippet shows how to add standard build options to a build.zig file, allowing control over optimization and safety checks. ```zig const std = @import("std"); pub fn build(b: *std.Build) void { const optimize = b.standardOptimizeOption(.{}); const exe = b.addExecutable(.{ .name = "example", .root_module = b.createModule(.{ .root_source_file = b.path("example.zig"), .optimize = optimize, }), }); b.default_step.dependOn(&exe.step); } ``` -------------------------------- ### Zig Basic Slices Example Source: https://ziglang.org/documentation/0.16.0 Demonstrates the creation and usage of slices from arrays, including differences between compile-time and runtime slicing, and slice bounds checking. ```zig const expectEqual = @import("std").testing.expectEqual; const expectEqualSlices = @import("std").testing.expectEqualSlices; test "basic slices" { var array = [_]i32{ 1, 2, 3, 4 }; var known_at_runtime_zero: usize = 0; _ = &known_at_runtime_zero; const slice = array[known_at_runtime_zero..array.len]; // alternative initialization using result location const alt_slice: []const i32 = &.{ 1, 2, 3, 4 }; try expectEqualSlices(i32, slice, alt_slice); try expectEqual([]i32, @TypeOf(slice)); try expectEqual(&array[0], &slice[0]); try expectEqual(array.len, slice.len); // If you slice with comptime-known start and end positions, the result is // a pointer to an array, rather than a slice. const array_ptr = array[0..array.len]; try expectEqual(*[array.len]i32, @TypeOf(array_ptr)); // You can perform a slice-by-length by slicing twice. This allows the compiler // to perform some optimisations like recognising a comptime-known length when // the start position is only known at runtime. var runtime_start: usize = 1; _ = &runtime_start; const length = 2; const array_ptr_len = array[runtime_start..][0..length]; try expectEqual(*[length]i32, @TypeOf(array_ptr_len)); // Using the address-of operator on a slice gives a single-item pointer. try expectEqual(*i32, @TypeOf(&slice[0])); // Using the `ptr` field gives a many-item pointer. try expectEqual([*]i32, @TypeOf(slice.ptr)); try expectEqual(@intFromPtr(slice.ptr), @intFromPtr(&slice[0])); // Slices have array bounds checking. If you try to access something out // of bounds, you'll get a safety check failure: slice[10] += 1; // Note that `slice.ptr` does not invoke safety checking, while `&slice[0]` // asserts that the slice has len > 0. // Empty slices can be created like this: const empty1 = &[0]u8{}; // If the type is known you can use this short hand: const empty2: []u8 = &.{}; try expectEqual(0, empty1.len); try expectEqual(0, empty2.len); // A zero-length initialization can always be used to create an empty slice, even if the slice is mutable. // This is because the pointed-to data is zero bits long, so its immutability is irrelevant. } ``` -------------------------------- ### Zig String Slices Example Source: https://ziglang.org/documentation/0.16.0 Demonstrates using slices for string literals in Zig, including concatenation and handling UTF-8 characters. ```zig const std = @import("std"); const expectEqual = std.testing.expectEqual; const expectEqualStrings = std.testing.expectEqualStrings; const fmt = std.fmt; test "using slices for strings" { // Zig has no concept of strings. String literals are const pointers // to null-terminated arrays of u8, and by convention parameters // that are "strings" are expected to be UTF-8 encoded slices of u8. // Here we coerce *const [5:0]u8 and *const [6:0]u8 to []const u8 const hello: []const u8 = "hello"; const world: []const u8 = "δΈ–η•Œ"; var all_together: [100]u8 = undefined; // You can use slice syntax with at least one runtime-known index on an // array to convert an array into a slice. var start: usize = 0; _ = &start; const all_together_slice = all_together[start..]; // String concatenation example. const hello_world = try fmt.bufPrint(all_together_slice, "{s} {s}", .{ hello, world }); // Generally, you can use UTF-8 and not worry about whether something is a // string. If you don't need to deal with individual characters, no need // to decode. try expectEqualStrings("hello δΈ–η•Œ", hello_world); } ``` -------------------------------- ### Running Zig Tests Source: https://ziglang.org/documentation/0.16.0 This example demonstrates how to execute Zig tests from the command line using the `zig test` command. It shows the expected output for successful test execution. ```shell $ `zig test testing_introduction.zig` 1/2 testing_introduction.test.expect addOne adds one to 41...OK 2/2 testing_introduction.decltest.addOne...OK All 2 tests passed. ``` -------------------------------- ### Sentinel-Terminated Slicing in Zig Source: https://ziglang.org/documentation/0.16.0 Shows how to create a sentinel-terminated slice using the `data[start..end :x]` syntax. This example creates a slice with a runtime-known length and a sentinel value. ```zig const std = @import("std"); const expectEqual = std.testing.expectEqual; test "0-terminated slicing" { var array = [_]u8{ 3, 2, 1, 0, 3, 2, 1, 0 }; var runtime_length: usize = 3; _ = &runtime_length; const slice = array[0..runtime_length :0]; try expectEqual([:0]u8, @TypeOf(slice)); try expectEqual(3, slice.len); } ``` -------------------------------- ### Zig Type Coercion Examples Source: https://ziglang.org/documentation/0.16.0 Provides examples of type coercion in Zig, covering variable declarations, function calls, and the use of the '@as' builtin. These demonstrate unambiguous and safe type conversions. ```zig test "type coercion - variable declaration" { const a: u8 = 1; const b: u16 = a; _ = b; } test "type coercion - function call" { const a: u8 = 1; foo(a); } fn foo(b: u16) void { _ = b; } test "type coercion - @as builtin" { const a: u8 = 1; const b = @as(u16, a); _ = b; } ``` -------------------------------- ### Example of Zig Builtin Package Contents Source: https://ziglang.org/documentation/0.16.0 Illustrates the various compile-time constants available through the `builtin` package, including Zig version, target details, and build configurations. ```zig const std = @import("std"); /// Zig version. When writing code that supports multiple versions of Zig, prefer /// feature detection (i.e. with `@hasDecl` or `@hasField`) over version checks. pub const zig_version = std.SemanticVersion.parse(zig_version_string) catch unreachable; pub const zig_version_string = "0.16.0-dev.3132+fd2718f82"; pub const zig_backend = std.builtin.CompilerBackend.stage2_x86_64; pub const output_mode: std.builtin.OutputMode = .Exe; pub const link_mode: std.builtin.LinkMode = .static; pub const unwind_tables: std.builtin.UnwindTables = .async; pub const is_test = false; pub const single_threaded = false; pub const abi: std.Target.Abi = .gnu; pub const cpu: std.Target.Cpu = .{ .arch = .x86_64, .model = &std.Target.x86.cpu.znver4, .features = std.Target.x86.featureSet(&.{ ."64bit", .adx, .aes, .allow_light_256_bit, .avx, .avx2, .avx512bf16, .avx512bitalg, .avx512bw, .avx512cd, .avx512dq, .avx512f, .avx512ifma, .avx512vbmi, .avx512vbmi2, .avx512vl, .avx512vnni, .avx512vpopcntdq, .bmi, .bmi2, .branchfusion, .clflushopt, .clwb, .clzero, .cmov, .crc32, .cx16, .cx8, .evex512, .f16c, .fast_15bytenop, .fast_bextr, .fast_dpwssd, .fast_imm16, .fast_lzcnt, .fast_movbe, .fast_scalar_fsqrt, .fast_scalar_shift_masks, .fast_variable_perlane_shuffle, .fast_vector_fsqrt, .fma, .fsgsbase, .fsrm, .fxsr, .gfni, .idivq_to_divl, .invpcid, .lzcnt, .macrofusion, .mmx, .movbe, .mwaitx, .nopl, .pclmul, .pku, .popcnt, .prfchw, .rdpid, .rdpru, .rdrnd, .rdseed, .sahf, .sbb_dep_breaking, .sha, .shstk, .smap, .smep, .sse, .sse2, .sse3, .sse4_1, .sse4_2, .sse4a, .ssse3, .vaes, .vpclmulqdq, .vzeroupper, .wbnoinvd, .x87, .xsave, .xsavec, .xsaveopt, .xsaves, }), }; pub const os: std.Target.Os = .{ .tag = .linux, .version_range = .{.linux = .{ .range = .{ .min = .{ .major = 6, .minor = 18, .patch = 9, }, .max = .{ .major = 6, .minor = 18, .patch = 9, }, }, .glibc = .{ .major = 2, .minor = 39, .patch = 0, }, .android = 29, }}, }; pub const target: std.Target = .{ .cpu = cpu, .os = os, .abi = abi, .ofmt = object_format, .dynamic_linker = .init("/nix/store/vr7ds8vwbl2fz7pr221d5y0f8n9a5wda-glibc-2.40-218/lib/ld-linux-x86-64.so.2"), }; pub const object_format: std.Target.ObjectFormat = .elf; pub const mode: std.builtin.OptimizeMode = .Debug; pub const link_libc = false; pub const link_libcpp = false; pub const have_error_return_tracing = true; pub const valgrind_support = true; pub const sanitize_thread = false; pub const fuzz = false; pub const position_independent_code = false; pub const position_independent_executable = false; pub const strip_debug_info = false; pub const code_model: std.builtin.CodeModel = .default; pub const omit_frame_pointer = false; ``` -------------------------------- ### Equivalent Loop for Zig Switch Continue Source: https://ziglang.org/documentation/0.16.0 Provides a loop-based equivalent to the `switch continue` example, illustrating the semantic behavior of the labeled switch with `continue`. ```zig const std = @import("std"); test "switch continue, equivalent loop" { var sw: i32 = 5; while (true) { switch (sw) { 5 => { sw = 4; continue; }, 2...4 => |v| { if (v > 3) { sw = 2; continue; } else if (v == 3) { break; } sw = 1; continue; }, 1 => return, else => unreachable, } } } ``` -------------------------------- ### Zig Stack Trace Example (for comparison) Source: https://ziglang.org/documentation/0.16.0 Illustrates a scenario using `@panic` to simulate a traditional stack trace, highlighting the difference in error reporting compared to Zig's Error Return Traces. ```zig pub fn main() void { foo(12); } fn foo(x: i32) void { if (x >= 5) { bar(); } else { bang2(); } } fn bar() void { if (baz()) { quux(); } else { hello(); } } fn baz() bool { return bang1(); } fn quux() void { bang2(); } fn hello() void { bang2(); } fn bang1() bool { return false; } fn bang2() void { @panic("PermissionDenied"); } ``` -------------------------------- ### Process Command-Line Arguments with WASI Source: https://ziglang.org/documentation/0.16.0 Example of using Zig's standard library to process command-line arguments in a WASI environment. The `init.minimal.args.toSlice` function is used to access arguments. ```zig const std = @import("std"); pub fn main(init: std.process.Init) !void { const args = try init.minimal.args.toSlice(init.arena.allocator()); for (0.., args) |i, arg| { std.debug.print("{d}: {s}\n", .{ i, arg }); } } ``` ```shell $ `zig build-exe wasi_args.zig -target wasm32-wasi` ``` ```shell $ `wasmtime wasi_args.wasm 123 hello` 0: wasi_args.wasm 1: 123 2: hello ``` -------------------------------- ### Zig noreturn with ExitProcess Example Source: https://ziglang.org/documentation/0.16.0 Demonstrates using `noreturn` with the `ExitProcess` function from the Windows API. This snippet shows how to handle errors by exiting the process. ```zig const std = @import("std"); const builtin = @import("builtin"); const native_arch = builtin.cpu.arch; const expectEqual = std.testing.expectEqual; const WINAPI: std.builtin.CallingConvention = if (native_arch == .x86) .{ .x86_stdcall = .{} } else .c; extern "kernel32" fn ExitProcess(exit_code: c_uint) callconv(WINAPI) noreturn; test "foo" { const value = bar() catch ExitProcess(1); try expectEqual(1234, value); } fn bar() anyerror!u32 { return 1234; } ``` -------------------------------- ### Zig Test Execution for Arrays Source: https://ziglang.org/documentation/0.16.0 Shows the shell command to run Zig tests for array examples and the expected output indicating all tests passed. ```shell $ `zig test test_arrays.zig` 1/4 test_arrays.test.iterate over an array...OK 2/4 test_arrays.test.modify an array...OK 3/4 test_arrays.test.compile-time array initialization...OK 4/4 test_arrays.test.array initialization with function calls...OK All 4 tests passed. ``` -------------------------------- ### Zig Wrapping Addition Operator Example Source: https://ziglang.org/documentation/0.16.0 Shows the wrapping addition operator (`+%`) for integers in Zig, which uses two's-complement wrapping behavior. ```zig @as(u32, 0xffffffff) +% 1 == 0 ``` -------------------------------- ### Shell Command to Compile and Run Zig Stack Trace Example Source: https://ziglang.org/documentation/0.16.0 Commands to compile the Zig code that uses `@panic` and execute it, demonstrating the resulting panic message and stack trace. ```shell $ `zig build-exe stack_trace.zig` $ `./stack_trace` thread 930211 panic: PermissionDenied /home/andy/src/zig/doc/langref/stack_trace.zig:38:5: 0x11d5e7a in bang2 (stack_trace.zig) @panic("PermissionDenied"); ^ /home/andy/src/zig/doc/langref/stack_trace.zig:30:10: 0x11d5efc in hello (stack_trace.zig) bang2(); ^ /home/andy/src/zig/doc/langref/stack_trace.zig:17:14: 0x11d5eb3 in bar (stack_trace.zig) hello(); ^ /home/andy/src/zig/doc/langref/stack_trace.zig:7:12: 0x11d5898 in foo (stack_trace.zig) bar(); ^ /home/andy/src/zig/doc/langref/stack_trace.zig:2:8: 0x11d5801 in main (stack_trace.zig) foo(12); ^ /home/andy/src/zig/lib/std/start.zig:685:59: 0x11d5121 in callMain (std.zig) if (fn_info.params.len == 0) return wrapMain(root.main()); ^ /home/andy/src/zig/lib/std/start.zig:190:5: 0x11d4b81 in _start (std.zig) asm volatile (switch (native_arch) { ^ (process terminated by signal) ``` -------------------------------- ### Zig Testing Namespace Examples Source: https://ziglang.org/documentation/0.16.0 Demonstrates the usage of `std.testing.expectEqual` for comparing values and `std.testing.expectError` for verifying expected errors in Zig tests. Ensure the `std` module is imported. ```zig const std = @import("std"); test "expectEqual demo" { const expected: i32 = 42; const actual = 42; // The first argument to `expectEqual` is the known, expected, result. // The second argument is the result of some expression. // The actual's type is casted to the type of expected. try std.testing.expectEqual(expected, actual); } test "expectError demo" { const expected_error = error.DemoError; const actual_error_union: anyerror!void = error.DemoError; // `expectError` will fail when the actual error is different than // the expected error. try std.testing.expectError(expected_error, actual_error_union); } ``` -------------------------------- ### Function Reflection Example Source: https://ziglang.org/documentation/0.16.0 Shows how to use Zig's function reflection capabilities to inspect function types, including parameter types, return types, and whether a function is generic. ```zig const std = @import("std"); const math = std.math; const testing = std.testing; test "fn reflection" { try testing.expectEqual(bool, @typeInfo(@TypeOf(testing.expect))."fn".params[0].type.?); try testing.expectEqual(testing.TmpDir, @typeInfo(@TypeOf(testing.tmpDir))."fn".return_type.?); try testing.expect(@typeInfo(@TypeOf(math.Log2Int))."fn".is_generic); } ``` -------------------------------- ### Shell Command to Compile and Run Zig Error Trace Example Source: https://ziglang.org/documentation/0.16.0 Commands to compile the Zig code into an executable and then run it to observe the error output, including the detailed Error Return Trace. ```shell $ `zig build-exe error_return_trace.zig` $ `./error_return_trace` error: PermissionDenied /home/andy/src/zig/doc/langref/error_return_trace.zig:34:5: 0x11d4b9c in bang1 (error_return_trace.zig) return error.FileNotFound; ^ /home/andy/src/zig/doc/langref/error_return_trace.zig:22:5: 0x11d4bfc in baz (error_return_trace.zig) try bang1(); ^ /home/andy/src/zig/doc/langref/error_return_trace.zig:38:5: 0x11d4c3c in bang2 (error_return_trace.zig) return error.PermissionDenied; ^ /home/andy/src/zig/doc/langref/error_return_trace.zig:30:5: 0x11d4d1c in hello (error_return_trace.zig) try bang2(); ^ /home/andy/src/zig/doc/langref/error_return_trace.zig:17:31: 0x11d4e2a in bar (error_return_trace.zig) error.FileNotFound => try hello(), ^ /home/andy/src/zig/doc/langref/error_return_trace.zig:7:9: 0x11d4f0a in foo (error_return_trace.zig) try bar(); ^ /home/andy/src/zig/doc/langref/error_return_trace.zig:2:5: 0x11d5011 in main (error_return_trace.zig) try foo(12); ^ ``` -------------------------------- ### Zig Test Execution for Multidimensional Arrays Source: https://ziglang.org/documentation/0.16.0 Shows the shell command to run Zig tests for multidimensional array examples and the expected output indicating all tests passed. ```shell $ `zig test test_multidimensional_arrays.zig` 1/1 test_multidimensional_arrays.test.multidimensional arrays...OK All 1 tests passed. ``` -------------------------------- ### Zig Error Return Trace Example Source: https://ziglang.org/documentation/0.16.0 Demonstrates how to use explicit error sets and the `try` keyword to propagate errors. This code shows how an error can be handled and then a new error returned, which is clearly visible in the Error Return Trace. ```zig pub fn main() !void { try foo(12); } fn foo(x: i32) !void { if (x >= 5) { try bar(); } else { try bang2(); } } fn bar() !void { if (baz()) { try quux(); } else |err| switch (err) { error.FileNotFound => try hello(), } } fn baz() !void { try bang1(); } fn quux() !void { try bang2(); } fn hello() !void { try bang2(); } fn bang1() !void { return error.FileNotFound; } fn bang2() !void { return error.PermissionDenied; } ``` -------------------------------- ### C Variadic Argument Start Source: https://ziglang.org/documentation/0.16.0 Implements the C `va_start` macro. Initializes a `VaList` object for use within a variadic function. Only valid inside such functions. ```zig @cVaStart() std.builtin.VaList ``` -------------------------------- ### Zig Module with Top-Level Doc Comments Source: https://ziglang.org/documentation/0.16.0 Demonstrates top-level doc comments (//! ) used to document an entire module or container. These comments are ignored if not at the start of a module. ```zig //! This module provides functions for retrieving the current date and //! time with varying degrees of precision and accuracy. It does not //! depend on libc, but will use functions from it if available. const S = struct { //! Top level comments are allowed inside a container other than a module, //! but it is not very useful. Currently, when producing the package //! documentation, these comments are ignored. }; ``` -------------------------------- ### Inline Function Example Source: https://ziglang.org/documentation/0.16.0 Demonstrates an inline function where compile-time known arguments propagate to the return value. This differs from normal function calls where arguments are runtime values. ```zig const std = @import("std"); pub fn main() void { if (foo(1200, 34) != 1234) { @compileError("bad"); } } inline fn foo(a: i32, b: i32) i32 { std.debug.print("runtime a = {} b = {}", .{ a, b }); return a + b; } ``` -------------------------------- ### Zig Optional Pointers Source: https://ziglang.org/documentation/0.16.0 Demonstrates the behavior of optional pointers in Zig. Optional pointers are the same size as regular pointers, with address 0 representing null. This example tests unwrapping and size comparison. ```zig const expectEqual = @import("std").testing.expectEqual; test "optional pointers" { // Pointers cannot be null. If you want a null pointer, use the optional // prefix `?` to make the pointer type optional. var ptr: ?*i32 = null; var x: i32 = 1; ptr = &x; try expectEqual(1, ptr.?.*); // Optional pointers are the same size as normal pointers, because pointer // value 0 is used as the null value. try expectEqual(@sizeOf(?*i32), @sizeOf(*i32)); } ``` -------------------------------- ### Generate First N Primes with Comptime Source: https://ziglang.org/documentation/0.16.0 This function calculates the first N prime numbers at compile time. It requires no special setup beyond defining the function. ```zig fn firstNPrimes(comptime n: usize) [n]i32 { var prime_list: [n]i32 = undefined; var next_index: usize = 0; var test_number: i32 = 2; while (next_index < prime_list.len) : (test_number += 1) { var test_prime_index: usize = 0; var is_prime = true; while (test_prime_index < next_index) : (test_prime_index += 1) { if (test_number % prime_list[test_prime_index] == 0) { is_prime = false; break; } } if (is_prime) { prime_list[next_index] = test_number; next_index += 1; } } return prime_list; } ``` -------------------------------- ### Get Field Byte Offset with @offsetOf Source: https://ziglang.org/documentation/0.16.0 Retrieves the byte offset of a specific field relative to the start of its containing struct. This is useful for memory layout calculations. ```zig @offsetOf(comptime T: type, comptime field_name: []const u8) comptime_int ``` -------------------------------- ### Zig Multiline String Literal Example Source: https://ziglang.org/documentation/0.16.0 Demonstrates how to define a multiline string literal in Zig using the '\\' token to span across lines and append newlines. ```zig const hello_world_in_c = \#include \ \int main(int argc, char **argv) { \ printf("hello world\n"); \ return 0; \} ; ``` -------------------------------- ### Zig noreturn Compatibility Example Source: https://ziglang.org/documentation/0.16.0 Shows how `noreturn` is compatible with other types in control flow. This example uses `return` as a `noreturn` expression in an `if` statement. ```zig fn foo(condition: bool, b: u32) void { const a = if (condition) b else return; _ = a; @panic("do something with a"); } test "noreturn" { foo(false, 1); } ``` -------------------------------- ### Building a Static C Library with Zig Source: https://ziglang.org/documentation/0.16.0 Compile a Zig file into a static library compatible with the C ABI. ```shell `zig build-lib mathtest.zig` ``` -------------------------------- ### Getting Tag Name with @tagName Source: https://ziglang.org/documentation/0.16.0 Shows how to use the `@tagName` builtin to get a compile-time string literal of the active union field name. ```zig const std = @import("std"); const expectEqualSlices = std.testing.expectEqualSlices; const Small2 = union(enum) { a: i32, b: bool, c: u8, }; test "@tagName" { try expectEqualSlices(u8, "a", @tagName(Small2.a)); } ``` -------------------------------- ### Zig Compile-Time Unreachable Type Example Source: https://ziglang.org/documentation/0.16.0 Illustrates that the type of `unreachable` is `noreturn` at compile-time. This example shows a compile-time assertion that fails because `unreachable` expressions are compile errors. ```zig const assert = @import("std").debug.assert; test "type of unreachable" { comptime { // The type of unreachable is noreturn. // However this assertion will still fail to compile because // unreachable expressions are compile errors. assert(@TypeOf(unreachable) == noreturn); } } ``` -------------------------------- ### Zig Inline While Loop Example Source: https://ziglang.org/documentation/0.16.0 Demonstrates an inline while loop that unrolls at compile time. Use inline loops when compile-time execution is necessary for semantics or when benchmarks prove a performance benefit. ```zig const expectEqual = @import("std").testing.expectEqual; test "inline while loop" { comptime var i = 0; var sum: usize = 0; inline while (i < 3) : (i += 1) { const T = switch (i) { 0 => f32, 1 => i8, 2 => bool, else => unreachable, }; sum += typeNameLength(T); } try expectEqual(9, sum); } fn typeNameLength(comptime T: type) usize { return @typeName(T).len; } ``` -------------------------------- ### Compile and Run Hello World Source: https://ziglang.org/documentation/0.16.0 Commands to compile a Zig 'Hello, World!' program and then execute it. ```shell $ `zig build-exe hello.zig` $ `./hello` Hello, World! ``` -------------------------------- ### Zig String Literal Example Source: https://ziglang.org/documentation/0.16.0 Demonstrates the type, length, indexing, and comparison of Zig string literals. Shows how to embed non-UTF-8 bytes and access individual bytes of Unicode characters. ```zig const print = @import("std").debug.print; const mem = @import("std").mem; // will be used to compare bytes pub fn main() void { const bytes = "hello"; print("{} ", .{@TypeOf(bytes)}); print("{d} ", .{bytes.len}); print("{c} ", .{bytes[1]}); print("{d} ", .{bytes[5]}); print("{} ", .{'e' == '\x65'}); print("{d} ", .{'\u{1f4a9}'}); print("{d} ", .{'πŸ’―'}); print("{u} ", .{'⚑'}); print("{} ", .{mem.eql(u8, "hello", "h\x65llo")}); print("{} ", .{mem.eql(u8, "πŸ’―", "\xf0\x9f\x92\xaf")}); const invalid_utf8 = "\xff\xfe"; // non-UTF-8 strings are possible with \xNN notation. print("0x{x} ", .{invalid_utf8[1]}); print("0x{x} ", .{"πŸ’―"[1]}); } ``` -------------------------------- ### Zig Compile-Time Variable and Loop Evaluation Source: https://ziglang.org/documentation/0.16.0 Demonstrates using 'comptime' variables and 'inline while' loops for compile-time evaluation. This example generates specialized versions of 'performFn' based on the 'prefix_char' argument, showcasing compile-time code generation. ```zig const expectEqual = @import("std").testing.expectEqual; const CmdFn = struct { name: []const u8, func: fn (i32) i32, }; const cmd_fns = [_]CmdFn{ CmdFn{ .name = "one", .func = one }, CmdFn{ .name = "two", .func = two }, CmdFn{ .name = "three", .func = three }, }; fn one(value: i32) i32 { return value + 1; } fn two(value: i32) i32 { return value + 2; } fn three(value: i32) i32 { return value + 3; } fn performFn(comptime prefix_char: u8, start_value: i32) i32 { var result: i32 = start_value; comptime var i = 0; inline while (i < cmd_fns.len) : (i += 1) { if (cmd_fns[i].name[0] == prefix_char) { result = cmd_fns[i].func(result); } } return result; } test "perform fn" { try expectEqual(6, performFn('t', 1)); try expectEqual(1, performFn('o', 0)); try expectEqual(99, performFn('w', 99)); } ``` -------------------------------- ### Zig Negation Operator Example Source: https://ziglang.org/documentation/0.16.0 Demonstrates the negation operator (`-`) for integers and floats in Zig. This can cause overflow for integers. ```zig -1 == 0 - 1 ``` -------------------------------- ### Declaring and Using Structs Source: https://ziglang.org/documentation/0.16.0 Demonstrates the declaration of structs, instantiation of struct instances, and the definition and usage of struct methods (functions within the struct's namespace). ```zig // Declare a struct. // Zig gives no guarantees about the order of fields and the size of // the struct but the fields are guaranteed to be ABI-aligned. const Point = struct { x: f32, y: f32, }; // Declare an instance of a struct. const p: Point = ΰͺ«ΰ«‹. .x = 0.12, .y = 0.34, }; // Functions in the struct's namespace can be called with dot syntax. const Vec3 = struct { x: f32, y: f32, z: f32, pub fn init(x: f32, y: f32, z: f32) Vec3 { return Vec3{ .x = x, .y = y, .z = z, }; } pub fn dot(self: Vec3, other: Vec3) f32 { return self.x * other.x + self.y * other.y + self.z * other.z; } }; test "dot product" { const v1 = Vec3.init(1.0, 0.0, 0.0); const v2 = Vec3.init(0.0, 1.0, 0.0); try expectEqual(0.0, v1.dot(v2)); // Other than being available to call with dot syntax, struct methods are // not special. You can reference them as any other declaration inside // the struct: try expectEqual(0.0, Vec3.dot(v1, v2)); } // Structs can have declarations. // Structs can have 0 fields. const Empty = struct { pub const PI = 3.14; }; test "struct namespaced variable" { try expectEqual(3.14, Empty.PI); try expectEqual(0, @sizeOf(Empty)); // Empty structs can be instantiated the same as usual. const does_nothing: Empty = ΰͺ«ΰ«‹; _ = does_nothing; } // Struct field order is determined by the compiler, however, a base pointer // can be computed from a field pointer: fn setYBasedOnX(x: *f32, y: f32) void { const point: *Point = @fieldParentPtr("x", x); point.y = y; } test "field parent pointer" { var point = Point{ .x = 0.1234, .y = 0.5678, }; setYBasedOnX(&point.x, 0.9); try expectEqual(0.9, point.y); } // Structs can be returned from functions. fn LinkedList(comptime T: type) type { return struct { pub const Node = struct { prev: ?*Node, next: ?*Node, data: T, }; first: ?*Node, last: ?*Node, len: usize, }; } test "linked list" { // Functions called at compile-time are memoized. try expectEqual(LinkedList(i32), LinkedList(i32)); const list = LinkedList(i32){ .first = null, .last = null, .len = 0, }; try expectEqual(0, list.len); // Since types are first class values you can instantiate the type // by assigning it to a variable: const ListOfInts = LinkedList(i32); try expectEqual(LinkedList(i32), ListOfInts); var node = ListOfInts.Node{ .prev = null, .next = null, .data = 1234, }; const list2 = LinkedList(i32){ .first = &node, .last = &node, .len = 1, }; // When using a pointer to a struct, fields can be accessed directly, // without explicitly dereferencing the pointer. // So you can do try expectEqual(1234, list2.first.?.data); // instead of try expectEqual(1234, list2.first.?.*.data); } const expectEqual = @import("std").testing.expectEqual; ``` -------------------------------- ### Define Line String in Zig Source: https://ziglang.org/documentation/0.16.0 Defines a line string, which starts with a backslash followed by non-control UTF-8 characters. ```zig line_string <- '\\\' non_control_utf8* [ \n]* ``` -------------------------------- ### Define Low-Level Entry Point with `_start` Source: https://ziglang.org/documentation/0.16.0 Declaring `_start` disables the default `std.start` logic, allowing for a custom low-level entry point. The `main` function will be ignored if `_start` is present. ```zig pub const _start = {}; ``` -------------------------------- ### Compile and Run Simple Hello World Source: https://ziglang.org/documentation/0.16.0 Commands to compile a Zig program using std.debug.print and then execute it. ```shell $ `zig build-exe hello_again.zig` $ `./hello_again` Hello, World! ``` -------------------------------- ### Empty Block Equivalence Source: https://ziglang.org/documentation/0.16.0 Shows that an empty block `{}` is equivalent to `void{}` and has the type `void`. This example verifies the type and value equality. ```zig const std = @import("std"); const expectEqual = std.testing.expectEqual; test { const a = {}; const b = void{}; try expectEqual(void, @TypeOf(a)); try expectEqual(void, @TypeOf(b)); try expectEqual(a, b); } ``` -------------------------------- ### Zig Wrapping Multiplication Operator Example Source: https://ziglang.org/documentation/0.16.0 Shows the wrapping multiplication operator (`*%`) for integers in Zig, which uses two's-complement wrapping behavior. ```zig @as(u8, 200) *% 2 == 144 ``` -------------------------------- ### Building a Shared C Library with Zig Source: https://ziglang.org/documentation/0.16.0 Compile a Zig file into a shared library compatible with the C ABI. ```shell `zig build-lib mathtest.zig -dynamic` ``` -------------------------------- ### Build and Run C Executable with Zig Build System Source: https://ziglang.org/documentation/0.16.0 Command to build the C executable using the Zig build system and then run it. ```shell $ `zig build test` 1379 ``` -------------------------------- ### Zig Multiplication Operator Example Source: https://ziglang.org/documentation/0.16.0 Demonstrates the standard multiplication operator for integers and floats in Zig. This operator can cause overflow for integers. ```zig 2 * 5 == 10 ``` -------------------------------- ### Zig Wrapping Negation Operator Example Source: https://ziglang.org/documentation/0.16.0 Shows the wrapping negation operator (`-%`) for integers in Zig, which uses two's-complement wrapping behavior. ```zig -%@as(i8, -128) == -128 ``` -------------------------------- ### Zig Wrapping Subtraction Operator Example Source: https://ziglang.org/documentation/0.16.0 Shows the wrapping subtraction operator (`-%`) for integers in Zig, which uses two's-complement wrapping behavior. ```zig @as(u8, 0) -% 1 == 255 ``` -------------------------------- ### Zig Test Execution Source: https://ziglang.org/documentation/0.16.0 Demonstrates how to run Zig tests from the command line. Ensure the test file is correctly named. ```shell $ `zig test test_container-level_comptime_expressions.zig` 1/1 test_container-level_comptime_expressions.test.variable values...OK All 1 tests passed. ``` -------------------------------- ### Zig Subtraction Operator Example Source: https://ziglang.org/documentation/0.16.0 Demonstrates the standard subtraction operator for integers and floats in Zig. This operator can cause overflow for integers. ```zig 2 - 5 == -3 ``` -------------------------------- ### Define Default Entry Point with `main` Source: https://ziglang.org/documentation/0.16.0 Use this for the primary entry point of an executable. `std.start` calls this function after initialization. It can return `void` (exit code 0) or `u8` (specified exit code). ```zig /// `std.start` imports this file using `@import("root")`, and uses this declaration as the program's /// user-provided entry point. It can return any of the following types: /// * `void` /// * `E!void`, for any error set `E` /// * `u8` /// * `E!u8`, for any error set `E` /// Returning a `void` value from this function will exit with code 0. /// Returning a `u8` value from this function will exit with the given status code. /// Returning an error value from this function will print an Error Return Trace and exit with code 1. pub fn main() void { std.debug.print("Hello, World!\n", .{}); } // If uncommented, this declaration would suppress the usual std.start logic, causing // the `main` declaration above to be ignored. //pub const _start = {}; const std = @import("std"); ``` -------------------------------- ### Define C-Compatible Entry Point with `export fn main` Source: https://ziglang.org/documentation/0.16.0 When linking against libc, you can use `export fn main` to match the C `main` function signature. This allows Zig executables to be called from C code or to use C runtime features. ```zig pub export fn main(argc: c_int, argv: [*]const [*:0]const u8) c_int { const args = argv[0..@intCast(argc)]; std.debug.print("Hello! argv[0] is '{s}'\n", .{args[0]}); return 0; } const std = @import("std"); ``` -------------------------------- ### Zig Addition Operator Example Source: https://ziglang.org/documentation/0.16.0 Demonstrates the standard addition operator for integers and floats in Zig. This operator can cause overflow for integers. ```zig 2 + 5 == 7 ``` -------------------------------- ### Compile Unattached Doc Comment Example Source: https://ziglang.org/documentation/0.16.0 Compiling Zig code with an unattached documentation comment results in a specific compile error. ```shell $ `zig build-obj unattached_doc-comment.zig` /home/andy/src/zig/doc/langref/unattached_doc-comment.zig:3:1: error: unattached documentation comment /// End of file ^~~~~~~~~~~~~~~ ``` -------------------------------- ### Hello World Program in Zig Source: https://ziglang.org/documentation/0.16.0 A basic 'Hello, World!' program that writes to standard output. Requires 'init' for I/O operations. ```zig const std = @import("std"); pub fn main(init: std.process.Init) !void { try std.io.File.stdout().writeStreamingAll(init.io, "Hello, World!\n"); } ``` -------------------------------- ### C Null Pointer Check Example Source: https://ziglang.org/documentation/0.16.0 A C code snippet demonstrating a common pattern for checking if a pointer is NULL before performing operations. ```c void do_a_thing(struct Foo *foo) { // do some stuff ``` -------------------------------- ### Simple Hello World with Debug Print Source: https://ziglang.org/documentation/0.16.0 A simplified 'Hello, World!' program using std.debug.print for formatted output to stderr. The '!' can be omitted from main's return type as no errors are returned. ```zig const std = @import("std"); pub fn main() void { std.debug.print("Hello, {s}!\n", .{"World"}); } ``` -------------------------------- ### Compile Invalid Doc Comment Example Source: https://ziglang.org/documentation/0.16.0 Attempting to compile Zig code with an invalid doc comment placement will result in a compile error. ```shell $ `zig build-obj invalid_doc-comment.zig` /home/andy/src/zig/doc/langref/invalid_doc-comment.zig:1:16: error: expected type expression, found 'a document comment' /// doc-comment ^ ``` -------------------------------- ### Render Zig Standard Library Documentation Source: https://ziglang.org/documentation/0.16.0 Use the 'zig std' command to render the documentation for the Zig Standard Library locally. ```shell zig std ``` -------------------------------- ### Define Built-in Identifier Syntax in Zig Source: https://ziglang.org/documentation/0.16.0 Defines the syntax for built-in identifiers, which start with '@' followed by a letter or underscore, and then alphanumeric characters or underscores. ```zig BUILTINIDENTIFIER <- '@'[A-Za-z_][A-Za-z0-9_]* skip ```