├── examples ├── 02 Standard Library │ ├── 06 JSON.zig │ ├── 08 crypto.zig │ ├── 09 threads.zig │ ├── 11 stacks.zig │ ├── 12 sorting.zig │ ├── 01 allocators.zig │ ├── 02 ArrayList.zig │ ├── 03 filesystem.zig │ ├── 05 formatting.zig │ ├── 10 hash_maps.zig │ ├── 13 iterators.zig │ ├── 07 random_numbers.zig │ ├── 04 readers_and_writers.zig │ ├── 14 formatting_specifiers.zig │ └── 15 advanced_formatting.zig ├── 01 Language Basics │ ├── 16 enums.zig │ ├── 17 structs.zig │ ├── 18 unions.zig │ ├── 20 floats.zig │ ├── 24 optionals.zig │ ├── 25 comptime.zig │ ├── 26 opaque.zig │ ├── 29 vectors.zig │ ├── 30 imports.zig │ ├── 19 integer_rules.zig │ ├── 22 labelled_loops.zig │ ├── 21 labelled_blocks.zig │ ├── 27 anonymous_structs.zig │ ├── 23 loops_as_expressions.zig │ ├── 28 sentinel_termination.zig │ ├── 13 pointer_sized_ints.zig │ ├── 10 runtime_safety.zig │ ├── 14 many_item_pointers.zig │ ├── 08 functions.zig │ ├── 12 pointers.zig │ ├── 07 defer.zig │ ├── 09 switch.zig │ ├── 11 unreachable.zig │ ├── 01 assignment.zig │ ├── 05 for_loop.zig │ ├── 15 slices.zig │ ├── 02 arrays.zig │ ├── 06 errors.zig │ ├── 04 while_loop.zig │ └── 03 if.zig └── 03 Build System │ ├── 01 emit_an_executable.zig │ └── 02 cross_compilation.zig ├── .gitignore ├── assets ├── demo.gif └── mascot.png ├── .github ├── workflows │ ├── zig_tests.yml │ └── sync_zig_versions.yml ├── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md └── renovate.json ├── flake.nix ├── LICENSE ├── flake.lock └── README.md /examples/02 Standard Library/06 JSON.zig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/02 Standard Library/08 crypto.zig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/02 Standard Library/09 threads.zig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/02 Standard Library/11 stacks.zig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/02 Standard Library/12 sorting.zig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/02 Standard Library/01 allocators.zig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/02 Standard Library/02 ArrayList.zig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/02 Standard Library/03 filesystem.zig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/02 Standard Library/05 formatting.zig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/02 Standard Library/10 hash_maps.zig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/02 Standard Library/13 iterators.zig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/02 Standard Library/07 random_numbers.zig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Zig dirs 2 | /.zig-cache 3 | /zig-out 4 | -------------------------------------------------------------------------------- /examples/02 Standard Library/04 readers_and_writers.zig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/02 Standard Library/14 formatting_specifiers.zig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/02 Standard Library/15 advanced_formatting.zig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purefns/zig-bytes/HEAD/assets/demo.gif -------------------------------------------------------------------------------- /assets/mascot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/purefns/zig-bytes/HEAD/assets/mascot.png -------------------------------------------------------------------------------- /examples/01 Language Basics/16 enums.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn main() !void {} 4 | -------------------------------------------------------------------------------- /examples/01 Language Basics/17 structs.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn main() !void {} 4 | -------------------------------------------------------------------------------- /examples/01 Language Basics/18 unions.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn main() !void {} 4 | -------------------------------------------------------------------------------- /examples/01 Language Basics/20 floats.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn main() !void {} 4 | -------------------------------------------------------------------------------- /examples/01 Language Basics/24 optionals.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn main() !void {} 4 | -------------------------------------------------------------------------------- /examples/01 Language Basics/25 comptime.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn main() !void {} 4 | -------------------------------------------------------------------------------- /examples/01 Language Basics/26 opaque.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn main() !void {} 4 | -------------------------------------------------------------------------------- /examples/01 Language Basics/29 vectors.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn main() !void {} 4 | -------------------------------------------------------------------------------- /examples/01 Language Basics/30 imports.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn main() !void {} 4 | -------------------------------------------------------------------------------- /examples/01 Language Basics/19 integer_rules.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn main() !void {} 4 | -------------------------------------------------------------------------------- /examples/01 Language Basics/22 labelled_loops.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn main() !void {} 4 | -------------------------------------------------------------------------------- /examples/01 Language Basics/21 labelled_blocks.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn main() !void {} 4 | -------------------------------------------------------------------------------- /examples/01 Language Basics/27 anonymous_structs.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn main() !void {} 4 | -------------------------------------------------------------------------------- /examples/01 Language Basics/23 loops_as_expressions.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn main() !void {} 4 | -------------------------------------------------------------------------------- /examples/01 Language Basics/28 sentinel_termination.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn main() !void {} 4 | -------------------------------------------------------------------------------- /examples/03 Build System/01 emit_an_executable.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn main() void { 4 | std.io.getStdOut().writeAll( 5 | "Hello World!", 6 | ) catch unreachable; 7 | } 8 | -------------------------------------------------------------------------------- /examples/01 Language Basics/13 pointer_sized_ints.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const expectEqual = std.testing.expectEqual; 3 | 4 | test "usize and isize" { 5 | try expectEqual(@sizeOf(usize), @sizeOf(*u8)); 6 | try expectEqual(@sizeOf(isize), @sizeOf(*u8)); 7 | 8 | // This will print '4' on 32-bit machines, and '8' on 64-bit machines. 9 | std.debug.print(" OS pointer size: {d} bits ...", .{@sizeOf(*u8)}); 10 | } 11 | -------------------------------------------------------------------------------- /examples/01 Language Basics/10 runtime_safety.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | test "out of bounds, no safety" { 4 | @setRuntimeSafety(false); 5 | const a = [_]u8{ 1, 2, 3 }; 6 | 7 | var index: u8 = 5; 8 | _ = &index; 9 | 10 | const b = a[index]; 11 | _ = b; 12 | } 13 | 14 | test "out of bounds" { 15 | const a = [_]u8{ 1, 2, 3 }; 16 | 17 | var index: u8 = 5; 18 | _ = &index; 19 | 20 | const b = a[index]; 21 | _ = b; 22 | } 23 | -------------------------------------------------------------------------------- /examples/01 Language Basics/14 many_item_pointers.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const expectEqual = std.testing.expectEqual; 3 | 4 | test "many-item pointers" { 5 | const array = [_]i32{ 1, 2, 3, 4 }; 6 | var ptr: [*]const i32 = &array; 7 | 8 | try expectEqual(1, ptr[0]); 9 | ptr += 1; 10 | try expectEqual(2, ptr[0]); 11 | 12 | // Slicing a many-item pointer without an end is equivalent to 13 | // pointer arithmetic: `ptr[start..] = ptr + start` 14 | try expectEqual(ptr + 1, ptr[1..]); 15 | } 16 | -------------------------------------------------------------------------------- /examples/01 Language Basics/08 functions.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const expectEqual = std.testing.expectEqual; 3 | 4 | // DO NOT USE THIS IN PRODUCTION!!!1! 5 | fn square(x: u8) u8 { 6 | return x * x; 7 | } 8 | 9 | test "function" { 10 | const y = square(2); 11 | try expectEqual(u8, @TypeOf(y)); 12 | try expectEqual(4, y); 13 | } 14 | 15 | fn fibonacci(n: u16) u64 { 16 | if (n == 0 or n == 1) return n; 17 | return fibonacci(n - 1) + fibonacci(n - 2); 18 | } 19 | 20 | test "function recursion" { 21 | try expectEqual(832040, fibonacci(30)); 22 | } 23 | -------------------------------------------------------------------------------- /.github/workflows/zig_tests.yml: -------------------------------------------------------------------------------- 1 | on: 2 | pull_request: 3 | branches: 4 | - main 5 | workflow_dispatch: 6 | jobs: 7 | run_all: 8 | strategy: 9 | matrix: 10 | os: 11 | - freebsd # self-hosted FreeBSD runner 12 | - ubuntu-latest 13 | - macos-latest 14 | - windows-latest 15 | name: Test all on ${{ matrix.os }} 16 | runs-on: ${{ matrix.os }} 17 | steps: 18 | - uses: actions/checkout@v4 19 | - uses: purefns/setup-zig@main 20 | with: 21 | version: 0.13.0 22 | - run: zig build test 23 | -------------------------------------------------------------------------------- /examples/01 Language Basics/12 pointers.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const expectEqual = std.testing.expectEqual; 3 | 4 | fn addOne(num: *u8) void { 5 | num.* += 1; 6 | } 7 | 8 | test "pointers" { 9 | var x: u8 = 0; 10 | addOne(&x); 11 | try expectEqual(1, x); 12 | } 13 | 14 | test "const pointers" { 15 | var x: u8 = 1; 16 | 17 | const y = &x; 18 | y.* += 1; 19 | } 20 | 21 | // Trying to set a `*T` to 0 is illegal behavior (that will be punished). 22 | test "arrest this pointer" { 23 | var x: u16 = 0; 24 | _ = &x; 25 | 26 | var y: *u8 = @ptrFromInt(x); 27 | _ = &y; 28 | } 29 | -------------------------------------------------------------------------------- /examples/01 Language Basics/07 defer.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const expectEqual = std.testing.expectEqual; 3 | 4 | test "defer" { 5 | var x: i16 = -2; 6 | { 7 | // this gets executed at the end of the current block 8 | defer x += 5; 9 | // therefore `x` should still be -2 here 10 | try expectEqual(-2, x); 11 | } 12 | try expectEqual(3, x); 13 | } 14 | 15 | test "multiple defer" { 16 | var y: f32 = 5; 17 | { 18 | // multiple defer statements are executed in reverse order 19 | defer y += 2; 20 | defer y /= 2; 21 | } 22 | try expectEqual(4.5, y); 23 | } 24 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: purefns 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /examples/01 Language Basics/09 switch.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const expectEqual = std.testing.expectEqual; 3 | 4 | test "switch statement" { 5 | var x: i8 = 100; 6 | switch (x) { 7 | -1...1 => { 8 | x = -x; 9 | }, 10 | 10, 100 => { 11 | // Special considerations must be made 12 | // when dividing signed integers 13 | x = @divExact(x, 10); 14 | }, 15 | else => {}, 16 | } 17 | try expectEqual(10, x); 18 | } 19 | 20 | // The same thing, but as an expression: 21 | 22 | test "switch expression" { 23 | var x: i8 = 100; 24 | x = switch (x) { 25 | -1...1 => -x, 26 | 10, 100 => @divExact(x, 10), 27 | else => x, 28 | }; 29 | try expectEqual(10, x); 30 | } 31 | -------------------------------------------------------------------------------- /examples/01 Language Basics/11 unreachable.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const expectEqual = std.testing.expectEqual; 3 | 4 | fn asciiToUpper(x: u8) u8 { 5 | return switch (x) { 6 | 'a'...'z' => x + 'A' - 'a', 7 | 'A'...'Z' => x, 8 | // Using `unreachable` here tells the compiler that this branch 9 | // is impossible, which the optimiser can take advantage of. 10 | else => unreachable, 11 | }; 12 | } 13 | 14 | test "unreachable switch" { 15 | try expectEqual('R', asciiToUpper('r')); 16 | try expectEqual('C', asciiToUpper('C')); 17 | } 18 | 19 | test "unreachable" { 20 | const x: u8 = 5; 21 | // Since `unreachable` is of type `noreturn`, it can 22 | // coerce to `u8` no problem. 23 | const y: u8 = if (x == 4) 3 else unreachable; 24 | _ = y; 25 | } 26 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "A collection of runnable Zig examples, used as the companion to the 'Zig Bytes' series."; 3 | 4 | inputs = { 5 | nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; 6 | flake-parts.url = "github:hercules-ci/flake-parts"; 7 | }; 8 | 9 | outputs = 10 | { nixpkgs, flake-parts, ... }@inputs: 11 | flake-parts.lib.mkFlake { inherit inputs; } { 12 | systems = [ 13 | "aarch64-darwin" 14 | "aarch64-linux" 15 | "x86_64-darwin" 16 | "x86_64-linux" 17 | ]; 18 | 19 | perSystem = 20 | { lib, pkgs, ... }: 21 | { 22 | devShells.default = pkgs.mkShell { 23 | packages = with pkgs; [ 24 | # NOTE: keep this in sync with 'build.zig' 25 | zig_0_13 26 | ]; 27 | }; 28 | }; 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:recommended" 5 | ], 6 | "nix": { 7 | "enabled": true 8 | }, 9 | "lockFileMaintenance": { 10 | "enabled": true 11 | }, 12 | "customManagers": [ 13 | { 14 | "customType": "regex", 15 | "description": "Update Zig compiler version in various places", 16 | "fileMatch": [ 17 | "^build.zig$", 18 | "^README.md$", 19 | ".*/zig_tests.yml$" 20 | ], 21 | "matchStrings": [ 22 | "const required_zig = \"(?.*?)\";\\s", 23 | "\\s.*`(?.*?)`", 24 | "version: (?.*?)\\s" 25 | ], 26 | "datasourceTemplate": "github-releases", 27 | "packageNameTemplate": "ziglang/zig", 28 | "versioningTemplate": "semver-coerced" 29 | } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: purefns 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /examples/01 Language Basics/01 assignment.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn main() !void { 4 | // `const` indicates that a variable is immutable 5 | const name = "Zig Dog"; 6 | 7 | // `var` indicates that a variable is mutable 8 | var count: u32 = 0; 9 | 10 | // debug print to stderr, don't worry about the specifics right now 11 | std.debug.print("const name = {s}\n\n", .{name}); 12 | std.debug.print("var count = {d}\n", .{count}); 13 | 14 | // changing the mutable variable 15 | count += @as(u32, 1); // @as() performs explicit type coercion 16 | std.debug.print("var count = {d}\n\n", .{count}); 17 | 18 | // undefined coerces to any type 19 | const undefined_const: i32 = undefined; 20 | // you will see some strange behavior when this prints 21 | std.debug.print("const undefined_const = {d}\n", .{undefined_const}); 22 | 23 | // and `var` variables 24 | var undefined_var: i32 = undefined; 25 | undefined_var = -1; 26 | std.debug.print("var undefined_var = {d}\n", .{undefined_var}); 27 | } 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 purefns 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/sync_zig_versions.yml: -------------------------------------------------------------------------------- 1 | on: 2 | pull_request: 3 | branches: 4 | - main 5 | workflow_dispatch: 6 | jobs: 7 | compare_versions: 8 | name: Sync Zig versions across codebase 9 | runs-on: ubuntu-22.04 10 | steps: 11 | - uses: actions/checkout@v4 12 | - uses: DeterminateSystems/nix-installer-action@v13 13 | - uses: DeterminateSystems/magic-nix-cache-action@v7 14 | - name: Compare Zig versions 15 | shell: bash 16 | run: | 17 | sudo apt install -y ripgrep 18 | 19 | build_version="$(rg 'required_zig = "(.*)"' -Nor '$1' ./build.zig)" 20 | flake_version="$(nix develop --command zig version)" 21 | tests_version="$(rg 'version: (.*)' -Nor '$1' ./.github/workflows/zig_tests.yml)" 22 | 23 | if [[ 24 | "$build_version" != "$flake_version" || 25 | "$build_version" != "$tests_version" 26 | ]]; then 27 | printf 'FATAL: Zig versions are mismatched!\n\n' 28 | printf 'build.zig: %s\n' "$build_version" 29 | printf 'flake.nix: %s\n' "$flake_version" 30 | printf 'zig_tests.yml: %s\n' "$tests_version" 31 | exit 1 32 | else 33 | echo "Zig versions are synced. Exiting." 34 | exit 0 35 | fi 36 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-parts": { 4 | "inputs": { 5 | "nixpkgs-lib": "nixpkgs-lib" 6 | }, 7 | "locked": { 8 | "lastModified": 1722555600, 9 | "narHash": "sha256-XOQkdLafnb/p9ij77byFQjDf5m5QYl9b2REiVClC+x4=", 10 | "owner": "hercules-ci", 11 | "repo": "flake-parts", 12 | "rev": "8471fe90ad337a8074e957b69ca4d0089218391d", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "owner": "hercules-ci", 17 | "repo": "flake-parts", 18 | "type": "github" 19 | } 20 | }, 21 | "nixpkgs": { 22 | "locked": { 23 | "lastModified": 1724224976, 24 | "narHash": "sha256-Z/ELQhrSd7bMzTO8r7NZgi9g5emh+aRKoCdaAv5fiO0=", 25 | "owner": "NixOS", 26 | "repo": "nixpkgs", 27 | "rev": "c374d94f1536013ca8e92341b540eba4c22f9c62", 28 | "type": "github" 29 | }, 30 | "original": { 31 | "owner": "NixOS", 32 | "ref": "nixos-unstable", 33 | "repo": "nixpkgs", 34 | "type": "github" 35 | } 36 | }, 37 | "nixpkgs-lib": { 38 | "locked": { 39 | "lastModified": 1722555339, 40 | "narHash": "sha256-uFf2QeW7eAHlYXuDktm9c25OxOyCoUOQmh5SZ9amE5Q=", 41 | "type": "tarball", 42 | "url": "https://github.com/NixOS/nixpkgs/archive/a5d394176e64ab29c852d03346c1fc9b0b7d33eb.tar.gz" 43 | }, 44 | "original": { 45 | "type": "tarball", 46 | "url": "https://github.com/NixOS/nixpkgs/archive/a5d394176e64ab29c852d03346c1fc9b0b7d33eb.tar.gz" 47 | } 48 | }, 49 | "root": { 50 | "inputs": { 51 | "flake-parts": "flake-parts", 52 | "nixpkgs": "nixpkgs" 53 | } 54 | } 55 | }, 56 | "root": "root", 57 | "version": 7 58 | } 59 | -------------------------------------------------------------------------------- /examples/01 Language Basics/05 for_loop.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const expectEqual = std.testing.expectEqual; 3 | 4 | test "capture syntax" { 5 | const items = [_]u32{ 1, 3, 5 }; 6 | 7 | var sum: u32 = 0; 8 | for (items) |value| { 9 | sum += value; 10 | } 11 | 12 | try expectEqual(9, sum); 13 | } 14 | 15 | test "range syntax" { 16 | var sum: usize = 0; 17 | 18 | // Ranges in for loops are always exclusive, 19 | // meaning the final number is not included: 20 | for (0..5) |i| { 21 | sum += i; 22 | } 23 | 24 | try expectEqual(10, sum); 25 | } 26 | 27 | test "index value" { 28 | const items = [_]u32{ 1, 3, 5 }; 29 | var sum: usize = 0; 30 | 31 | // Use an unbounded range as the second item 32 | // to capture the current index of iteration: 33 | for (items, 0..) |value, i| { 34 | _ = value; 35 | sum += i; 36 | } 37 | 38 | try expectEqual(3, sum); 39 | } 40 | 41 | test "multiple objects" { 42 | const items_a = [_]usize{ 0, 1, 2 }; 43 | const items_b = [_]usize{ 3, 4, 5 }; 44 | var sum: usize = 0; 45 | 46 | // All lengths must be equal at the start of the loop, 47 | // otherwise detectable illegal behavior occurs. 48 | for (items_a, items_b) |a, b| { 49 | sum += a + b; 50 | } 51 | 52 | try expectEqual(15, sum); 53 | } 54 | 55 | test "value by reference" { 56 | var items = [_]u32{ 1, 2, 3 }; 57 | 58 | // Using a pointer capture: 59 | for (&items) |*value| { 60 | value.* += 1; 61 | } 62 | 63 | try expectEqual(2, items[0]); 64 | try expectEqual(3, items[1]); 65 | try expectEqual(4, items[2]); 66 | } 67 | 68 | test "for else" { 69 | const items = [_]u32{ 1, 7, 0, 4, 5 }; 70 | 71 | for (items) |value| { 72 | if (value == 4) break; 73 | } else { 74 | // Since `items` does indeed contain 4, 75 | // the break statement above is reached 76 | // and this block is never evaluated. 77 | return error.NotFound; 78 | } 79 | 80 | // do more stuff... 81 | } 82 | -------------------------------------------------------------------------------- /examples/03 Build System/02 cross_compilation.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const builtin = @import("builtin"); 3 | 4 | const math = std.math; 5 | 6 | const print = std.debug.print; 7 | const allocPrint = std.fmt.allocPrint; 8 | 9 | const MEM_KB = math.pow(usize, 2, 10); 10 | const MEM_MB: usize = MEM_KB * MEM_KB; 11 | const MAX_MEM_BYTES: usize = 1 * MEM_MB; 12 | 13 | const stderr = std.io.getStdErr(); 14 | const stdout = std.io.getStdOut(); 15 | 16 | const log = std.log.scoped(.main); 17 | pub fn main() !void { 18 | var output: [MAX_MEM_BYTES]u8 = undefined; 19 | var fba = std.heap.FixedBufferAllocator.init(&output); 20 | const allocator = fba.allocator(); 21 | 22 | var path_buf: [1024]u8 = undefined; 23 | const exe_path = try std.fs.selfExePath(&path_buf); 24 | 25 | if (builtin.os.tag == .linux) { 26 | const argv = &[_][]const u8{ 27 | "bash", 28 | "-c", 29 | try allocPrint(allocator, "set -x; readelf -h '{s}'", .{exe_path}), 30 | }; 31 | 32 | const child_log = std.log.scoped(.child); 33 | const result = std.process.Child.run(.{ 34 | .allocator = allocator, 35 | .argv = argv, 36 | .max_output_bytes = output.len, 37 | }) catch |err| { 38 | var dump_trace = false; 39 | switch (err) { 40 | error.FileNotFound => { 41 | dump_trace = true; 42 | child_log.err("Failed to find executable: {s}", .{argv[0]}); 43 | }, 44 | else => {}, 45 | } 46 | return if (dump_trace) { 47 | if (@errorReturnTrace()) |et| std.debug.dumpStackTrace(et.*); 48 | }; 49 | }; 50 | 51 | const exit_code = result.term.Exited; 52 | if (exit_code != 0) child_log.err("Process exited with code {d}:\n", .{exit_code}); 53 | 54 | try stderr.writeAll(result.stderr); 55 | try stdout.writeAll(result.stdout); 56 | } else if (builtin.os.tag == .windows or builtin.os.tag == .uefi) { 57 | log.err("Not yet implemented for Windows.", .{}); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /examples/01 Language Basics/15 slices.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const expect = std.testing.expect; 3 | const expectEqual = std.testing.expectEqual; 4 | const expectEqualSlices = std.testing.expectEqualSlices; 5 | 6 | test "slices" { 7 | var array = [_]u32{ 1, 2, 3, 4 }; 8 | var known_at_runtime_zero: usize = 0; 9 | _ = &known_at_runtime_zero; 10 | const slice = array[known_at_runtime_zero..array.len]; 11 | 12 | // a one-line version using result location 13 | const alt_slice: []const u32 = &.{ 1, 2, 3, 4 }; 14 | 15 | try expectEqualSlices(u32, slice, alt_slice); 16 | 17 | try expectEqual([]u32, @TypeOf(slice)); 18 | try expectEqual(&array[0], &slice[0]); 19 | try expectEqual(array.len, slice.len); 20 | 21 | // If you slice with comptime-known start and end positions, the result is a 22 | // pointer to an array, rather than a slice. 23 | const array_ptr = array[0..array.len]; 24 | try expectEqual(*[array.len]u32, @TypeOf(array_ptr)); 25 | 26 | // You can perform a slice-by-length by slicing twice. This allows the compiler 27 | // to perform some optimisations like recognzing a comptime-known length when 28 | // the start position is only known at runtime. 29 | var runtime_start: usize = 1; 30 | _ = &runtime_start; 31 | const length = 2; 32 | const array_ptr_len = array[runtime_start..][0..length]; 33 | try expectEqual(*[length]u32, @TypeOf(array_ptr_len)); 34 | 35 | // Using the address-of operator on a slice gives a single-item pointer. 36 | try expectEqual(*u32, @TypeOf(&slice[0])); 37 | // Using the `ptr` field gives a many-item pointer. 38 | try expectEqual([*]u32, @TypeOf(slice.ptr)); 39 | try expectEqual(@intFromPtr(&slice[0]), @intFromPtr(slice.ptr)); 40 | 41 | // Slices have array bounds checking. If you try to access something out 42 | // of bounds, you'll get a safety check failure: 43 | // 44 | // slice[10] += 1; 45 | 46 | // Note that `slice.ptr` does not invoke safety checking, while `&slice[0]` 47 | // asserts that the slice has len > 0. 48 | } 49 | 50 | test "strings, a.k.a slices" { 51 | // Zig doesn't have strings. String literals are really just `*const [n:0]u8`, 52 | // and parameters that are "strings" are expected to be UTF-8 encoded slices of `u8`. 53 | // Here, we coerce string literals (pointers) to slices. 54 | const hello: []const u8 = "hello"; 55 | const world: []const u8 = "世界"; 56 | 57 | var buf: [100]u8 = undefined; 58 | 59 | // You can use slice syntax with at least one runtime-known index on an array 60 | // to convert it to a slice. 61 | var start: usize = 0; 62 | _ = &start; 63 | const buf_slice = buf[start..]; 64 | 65 | // An example of string concatenation: 66 | const hello_world = try std.fmt.bufPrint(buf_slice, "{s} {s}", .{ hello, world }); 67 | 68 | // You can generally use UTF-8 and not worry about whether something is a string. 69 | // If you don't need to deal with individual characters, don't decode! 70 | try expect(std.mem.eql(u8, hello_world, "hello 世界")); 71 | } 72 | -------------------------------------------------------------------------------- /examples/01 Language Basics/02 arrays.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | // Initialization using an array literal: 4 | const hello = [_]u8{ 'H', 'e', 'l', 'l', 'o' }; 5 | 6 | // Using result location: 7 | const alt_hello: [5]u8 = .{ 'H', 'e', 'l', 'l', 'o' }; 8 | 9 | // Using a string literal: 10 | const same_hello = "Hello"; 11 | 12 | comptime { 13 | // All of them are all the same 14 | std.debug.assert(std.mem.eql(u8, &hello, &alt_hello)); 15 | std.debug.assert(std.mem.eql(u8, &hello, same_hello)); 16 | 17 | // Get the size of an array 18 | std.debug.assert(hello.len == 5); 19 | } 20 | 21 | test "iterate over an array" { 22 | var sum: usize = 0; 23 | for (hello) |byte| { 24 | sum += byte; 25 | } 26 | try std.testing.expectEqual('H' + 'e' + 'l' * 2 + 'o', sum); 27 | } 28 | 29 | // A modifiable array: 30 | var items: [100]u8 = undefined; 31 | 32 | test "modifiable array" { 33 | // assigning by index: 34 | for (0..items.len) |i| { 35 | items[i] = @intCast(i); 36 | } 37 | // using a many-item pointer 38 | for (&items, 0..) |*item, i| { 39 | item.* = @intCast(i); 40 | } 41 | 42 | try std.testing.expectEqual(10, items[10]); 43 | try std.testing.expectEqual(99, items[99]); 44 | } 45 | 46 | // Array concatenation works if the values are known at compile time: 47 | const array_one = [_]u32{ 1, 2, 3, 4 }; 48 | const array_two = [_]u32{ 5, 6, 7, 8 }; 49 | const both = array_one ++ array_two; 50 | comptime { 51 | std.debug.assert(std.mem.eql(u32, &both, &[_]u32{ 1, 2, 3, 4, 5, 6, 7, 8 })); 52 | } 53 | 54 | // Remember that string literals are also arrays: 55 | const world = "world"; 56 | const hello_world = hello ++ " " ++ world; 57 | 58 | // Use '**' to repeat elements: 59 | const pattern = "zig" ** 3; 60 | comptime { 61 | std.debug.assert(std.mem.eql(u8, pattern, "zigzigzig")); 62 | } 63 | 64 | // Initialize an array to zero: 65 | const zeroes = [_]u8{0} ** 10; 66 | comptime { 67 | std.debug.assert(zeroes.len == 10); 68 | std.debug.assert(zeroes[5] == 0); 69 | } 70 | 71 | const Point = struct { 72 | x: u32, 73 | y: u32, 74 | }; 75 | 76 | // Initialize an array at compile-time: 77 | var comptime_array = blk: { 78 | var initial_value: [10]Point = undefined; 79 | for (&initial_value, 0..) |*pt, i| { 80 | pt.* = Point{ 81 | .x = @intCast(i), 82 | .y = @intCast(i * 2), 83 | }; 84 | } 85 | break :blk initial_value; 86 | }; 87 | 88 | test "comptime array initialization" { 89 | try std.testing.expectEqual(3, comptime_array[3].x); 90 | try std.testing.expectEqual(6, comptime_array[3].y); 91 | } 92 | 93 | fn makePoint(x: u32) Point { 94 | return .{ 95 | .x = x, 96 | .y = x * 2, 97 | }; 98 | } 99 | 100 | var another_array = [_]Point{makePoint(3)} ** 10; 101 | 102 | test "array initialization with function calls" { 103 | try std.testing.expectEqual(3, another_array[4].x); 104 | try std.testing.expectEqual(6, another_array[4].y); 105 | try std.testing.expectEqual(10, another_array.len); 106 | } 107 | -------------------------------------------------------------------------------- /examples/01 Language Basics/06 errors.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const expectEqual = std.testing.expectEqual; 3 | 4 | // An error set is very similar to an enum: 5 | const FileOpenError = error{ 6 | AccessDenied, 7 | OutOfMemory, 8 | FileNotFound, 9 | }; 10 | 11 | // They can also have just one item: 12 | const AllocationError = error{OutOfMemory}; 13 | 14 | test "coercing error sets" { 15 | // Since `AllocationError` is a subset of `FileOpenError`, it 16 | // can coerce to the `FileOpenError` type. 17 | const err: FileOpenError = AllocationError.OutOfMemory; 18 | try expectEqual(FileOpenError.OutOfMemory, err); 19 | 20 | // Coercing from a superset to a subset is not allowed, however. 21 | // If the comments below are removed, this will fail to compile. 22 | // 23 | // const err2: AllocationError = FileOpenError.OutOfMemory; 24 | // _ = err2; 25 | } 26 | 27 | const SystemError = FileOpenError || AllocationError; 28 | 29 | test "merging error sets" { 30 | // As before, the subset `AllocationError` can also coerce 31 | // to the superset of `SystemError`. 32 | const err: SystemError = AllocationError.OutOfMemory; 33 | try expectEqual(SystemError.OutOfMemory, err); 34 | } 35 | 36 | test "error unions" { 37 | // An error union is like a burrito, where you have to unwrap it 38 | // to get to the stuff inside; it can either be good (some data), 39 | // or bad (an error), and it's up to you to deal with it: 40 | const burrito: AllocationError!u16 = 10; 41 | 42 | // In Zig, `catch` is how you unwrap that burrito. Here we are 43 | // returning a default value, but you can also use a value of 44 | // type `noreturn` (the type of `return`, `while (true)`, etc.) 45 | const unburrito = burrito catch 0; 46 | 47 | // Our burrito is nothing but good inside: 48 | try expectEqual(10, unburrito); 49 | } 50 | 51 | // Omit the error set in a function return type to let it be inferred: 52 | fn createFile() !void { 53 | return error.OutOfMemory; 54 | } 55 | 56 | test "inferred error set" { 57 | // Type coercion successfully takes place 58 | const x: AllocationError!void = createFile(); 59 | 60 | // In order to ignore error unions, it must also be unwrapped 61 | // using `try`, `catch`, or `if` 62 | _ = x catch {}; 63 | } 64 | 65 | test "try" { 66 | const burrito: error{NotGood}!u8 = 42; 67 | 68 | // Using `try` is like assuming that your burrito is fine and 69 | // eating the whole thing, no matter the consequences: 70 | const unburrito = try burrito; 71 | 72 | // If that had been an error instead, the program would panic and 73 | // this code would never be reached: 74 | try expectEqual(42, unburrito); 75 | } 76 | 77 | var fail_count: u8 = 0; 78 | 79 | fn fail() error{Failed}!void { 80 | // If an error is returned past this point, the statement after 81 | // the `errdefer` keyword will be evaluated before execution 82 | // returns to the caller of this function. 83 | errdefer fail_count += 1; 84 | 85 | // Go figure, it didn't work. Now, the `errdefer` above will be 86 | // evaluated, and then the error will finally be returned. 87 | return error.Failed; 88 | } 89 | 90 | test "errdefer" { 91 | fail() catch { 92 | // Since the `errdefer` statement above has been evaulated 93 | // by this point, 94 | try expectEqual(1, fail_count); 95 | return; 96 | }; 97 | } 98 | -------------------------------------------------------------------------------- /examples/01 Language Basics/04 while_loop.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const expect = std.testing.expect; 3 | const expectEqual = std.testing.expectEqual; 4 | 5 | test "while" { 6 | var a: u16 = 1; 7 | while (a < 4) { 8 | a *= 2; 9 | } 10 | try expectEqual(4, a); 11 | } 12 | 13 | test "while with break keyword" { 14 | var b: u8 = 1; 15 | while (true) { 16 | if (b == 8) break; 17 | b *= 2; 18 | } 19 | try expectEqual(8, b); 20 | } 21 | 22 | test "while with continue keyword" { 23 | var c: u8 = 1; 24 | while (true) { 25 | c *= 2; 26 | if (c < 16) continue; 27 | break; 28 | } 29 | try expectEqual(16, c); 30 | } 31 | 32 | test "while with continue expression" { 33 | var d: u8 = 1; 34 | while (d < 32) : (d *= 2) {} 35 | try expectEqual(32, d); 36 | } 37 | 38 | test "while with crazier continue expression" { 39 | var e: u8 = 1; 40 | var f: u8 = 1; 41 | while (e + f < 64) : ({ 42 | e *= 2; 43 | f *= 2; 44 | }) {} 45 | try expectEqual(64, e + f); 46 | } 47 | 48 | test "while expression" { 49 | try expect(rangeHasNumber(0, 10, 5)); 50 | try expect(!rangeHasNumber(0, 10, 15)); 51 | } 52 | 53 | fn rangeHasNumber(begin: usize, end: usize, number: usize) bool { 54 | var cur = begin; 55 | return while (cur < end) : (cur += 1) { 56 | if (cur == number) { 57 | break true; 58 | } 59 | } else false; 60 | } 61 | 62 | test "labelled while" { 63 | // Example of a nested break: 64 | outer: while (true) { 65 | while (true) { 66 | break :outer; 67 | } 68 | } 69 | 70 | // Example of a nested continue: 71 | var g: u8 = 1; 72 | outer: while (g < 128) : (g *= 2) { 73 | while (true) { 74 | continue :outer; 75 | } 76 | } 77 | try expectEqual(128, g); 78 | } 79 | 80 | test "while with optionals" { 81 | var h: u8 = 0; 82 | items_left = 4; 83 | while (eventuallyNullSequence()) |value| { 84 | h += value; 85 | } 86 | try expectEqual(6, h); 87 | 88 | // null capture with an else block 89 | var i: u8 = 0; 90 | items_left = 4; 91 | while (eventuallyNullSequence()) |value| { 92 | i += value; 93 | } else { 94 | try expectEqual(6, i); 95 | } 96 | 97 | // null capture with a continue expression 98 | var j: u8 = 0; 99 | items_left = 4; 100 | while (eventuallyNullSequence()) |value| : (j += 1) { 101 | j += value; 102 | } 103 | try expectEqual(10, j); 104 | } 105 | 106 | var items_left: u8 = undefined; 107 | fn eventuallyNullSequence() ?u8 { 108 | return if (items_left == 0) null else blk: { 109 | items_left -= 1; 110 | break :blk items_left; 111 | }; 112 | } 113 | 114 | test "while with error unions" { 115 | var k: u8 = 0; 116 | items_left = 4; 117 | while (eventuallyErrorSequence()) |value| { 118 | k += value; 119 | } else |err| { 120 | try expectEqual(error.OutOfItems, err); 121 | } 122 | } 123 | 124 | fn eventuallyErrorSequence() !u8 { 125 | return if (items_left == 0) error.OutOfItems else blk: { 126 | items_left -= 1; 127 | break :blk items_left; 128 | }; 129 | } 130 | 131 | // NOTE: It's recommended to only `inline` loops for one of two reasons: 132 | // - You need the loop to execute at comptime for the semantics to work. 133 | // - You have a benchmark to prove that doing so is measurably faster. 134 | 135 | test "inline while" { 136 | comptime var l: u8 = 0; 137 | var sum: usize = 0; 138 | inline while (l < 3) : (l += 1) { 139 | // Types can be used as first-class values now! 140 | const T = switch (l) { 141 | 0 => u65535, 142 | 1 => comptime_int, 143 | 2 => anyopaque, 144 | else => unreachable, 145 | }; 146 | sum += @typeName(T).len; 147 | } 148 | try expectEqual(27, sum); 149 | } 150 | -------------------------------------------------------------------------------- /examples/01 Language Basics/03 if.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const expect = std.testing.expect; 3 | const expectEqual = std.testing.expectEqual; 4 | 5 | // If statements and expressions have three uses, corresponding to three types: 6 | // - bool 7 | // - ?T 8 | // - anyerror!T 9 | 10 | test "if expression" { 11 | // If expressions are used rather than ternary expressions: 12 | 13 | const a: u32 = 5; 14 | const b: u32 = 4; 15 | const result = if (a != b) 9001 else 0; 16 | try expectEqual(9001, result); 17 | } 18 | 19 | test "if boolean" { 20 | // If statements that test for true: 21 | 22 | const a: u32 = 3; 23 | const b: u32 = 4; 24 | if (a != b) { 25 | try expect(true); 26 | } else if (a == 7) { 27 | unreachable; 28 | } else { 29 | unreachable; 30 | } 31 | 32 | // The else is optional: 33 | if (a != b) { 34 | try expect(true); 35 | } 36 | } 37 | 38 | test "if optional" { 39 | // If statements that test for null: 40 | 41 | const a: ?u32 = 0; 42 | if (a) |value| { 43 | try expectEqual(0, value); 44 | } else { 45 | unreachable; 46 | } 47 | 48 | const b: ?u32 = null; 49 | if (b) |_| { 50 | unreachable; 51 | } else { 52 | try expect(true); 53 | } 54 | 55 | // The else is optional: 56 | if (a) |value| { 57 | try expectEqual(0, value); 58 | } 59 | 60 | // To test for just `null`, use the binary equality operator: 61 | if (b == null) { 62 | try expect(true); 63 | } 64 | 65 | // Access the value by reference using a pointer capture: 66 | var c: ?u32 = 3; 67 | if (c) |*value| { 68 | value.* = 7; 69 | } 70 | 71 | if (c) |value| { 72 | try expectEqual(7, value); 73 | } else { 74 | unreachable; 75 | } 76 | } 77 | 78 | test "if error union" { 79 | // If statements that test for errors: 80 | 81 | // An example of an error union containing a non-error value: 82 | const a: anyerror!u32 = 0; 83 | if (a) |value| { 84 | try expectEqual(0, value); 85 | } else |err| { 86 | _ = err; 87 | unreachable; 88 | } 89 | 90 | // An example of an error union containing an error value: 91 | const b: anyerror!u32 = error.BadValue; 92 | if (b) |value| { 93 | _ = value; 94 | unreachable; 95 | } else |err| { 96 | try expectEqual(error.BadValue, err); 97 | } 98 | 99 | // The else and |err| capture is strictly required. 100 | if (a) |value| { 101 | try expectEqual(0, value); 102 | } else |_| {} 103 | 104 | // To check only the error value, use an empty block expression. 105 | if (b) |_| {} else |err| { 106 | try expectEqual(error.BadValue, err); 107 | } 108 | 109 | // Access the value by reference using a pointer capture. 110 | var c: anyerror!u32 = 3; 111 | if (c) |*value| { 112 | value.* = 7; 113 | } else |_| { 114 | unreachable; 115 | } 116 | 117 | if (c) |value| { 118 | try expectEqual(7, value); 119 | } else |_| { 120 | unreachable; 121 | } 122 | } 123 | 124 | test "if error union with optional" { 125 | // If statements and expressions test for errors before unwrapping optionals. 126 | // The |optional_value| capture's type is ?u32. 127 | 128 | const a: anyerror!?u32 = 0; 129 | if (a) |optional_value| { 130 | try expectEqual(0, optional_value.?); 131 | } else |err| { 132 | _ = err; 133 | unreachable; 134 | } 135 | 136 | const b: anyerror!?u32 = null; 137 | if (b) |optional_value| { 138 | try expectEqual(null, optional_value); 139 | } else |_| { 140 | unreachable; 141 | } 142 | 143 | const c: anyerror!?u32 = error.BadValue; 144 | if (c) |optional_value| { 145 | _ = optional_value; 146 | unreachable; 147 | } else |err| { 148 | try expectEqual(error.BadValue, err); 149 | } 150 | 151 | // Access the value by reference by using a pointer capture each time: 152 | var d: anyerror!?u32 = 3; 153 | if (d) |*optional_value| { 154 | if (optional_value.*) |*value| { 155 | value.* = 7; 156 | } 157 | } else |_| { 158 | unreachable; 159 | } 160 | 161 | if (d) |optional_value| { 162 | try expectEqual(7, optional_value.?); 163 | } else |_| { 164 | unreachable; 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | [![Contributors][contributors-shield]][contributors-url] 5 | [![Forks][forks-shield]][forks-url] 6 | [![Stargazers][stars-shield]][stars-url] 7 | [![Issues][issues-shield]][issues-url] 8 | [![MIT License][license-shield]][license-url] 9 | [![YouTube Playlist][youtube-shield]][youtube-url] 10 | 11 | 12 | 13 |
14 |
15 |

Zig Bytes

16 | 17 | 18 | ZigIsGreat mascot 19 | 20 | 21 |
22 |

23 | The companion project to my Zig Bytes series, available as a standalone set of runnable examples. 24 |
25 |
26 | Report Bug 27 | · 28 | Request Feature 29 |
30 |
31 |

32 |
33 | 34 | 35 | 36 | 37 |
38 | Table of Contents 39 |
    40 |
  1. Compatibility
  2. 41 |
  3. 42 | Getting Started 43 | 48 |
  4. 49 |
  5. Roadmap
  6. 50 |
  7. Contributing
  8. 51 |
  9. License
  10. 52 |
  11. Contact
  12. 53 |
  13. Acknowledgments
  14. 54 |
55 |
56 | 57 | 58 | 59 | 60 | ## Compatibility 61 | 62 | This project currently has support for the following systems: 63 | 64 |
65 |
66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 |
OSSupport level
LinuxFull
WindowsWIP
FreeBSDWIP
MacOSWIP
88 |
89 | 90 | Note: 91 | This is the main branch, which means there are probably bugs and missing sections. 92 |
93 | This repository as a whole is also currently unfinished, which will likely make these issues worse. 94 |
95 | Please keep these things in mind when reporting bugs or other issues. 96 |
97 |
98 | A tagged release for Zig version 0.13.0 is currently being worked on. 99 |
100 |
101 | 102 |

(back to top)

103 | 104 | 105 | 106 | 107 | ## Getting Started 108 | 109 | ### Clone the repo 110 | 111 | Run the following commands to clone the repository and enter the project directory: 112 | 113 | ```bash 114 | git clone https://github.com/purefns/zig-bytes 115 | cd zig-bytes 116 | ``` 117 | 118 | 119 | ### Install Zig 120 | 121 | You will need to have the Zig compiler installed on your system. 122 | 123 | 124 | **The current requred version is `0.13.0`.** 125 | 126 | You can install it via a number of different methods, with availability depending on your OS: 127 | 128 | * Using a [pre-built binary](https://ziglang.org/download/) 129 | - This is the recommended option for most people. Make sure to download the correct option for your operating system 130 | and CPU architecture. 131 | * Using [a package manager](https://github.com/ziglang/zig/wiki/Install-Zig-from-a-Package-Manager) 132 | - This can be fine if your distribution/package manager's repositories are up-to-date, but a majority of them are not. 133 | This is likely due to the fast development speed of Zig - if you have a compatible version available to install, 134 | please feel free to do so. 135 | 136 | There is also a `flake.nix` available that includes a devshell set up with the necessary dependencies. 137 | To use it, just run the following command in the project directory: 138 | 139 | ```bash 140 | nix develop 141 | ``` 142 | 143 | 144 | ### Usage 145 | 146 | To get started with the first example just run `zig build`. 147 | 148 | To run a specific example use the `-Dexample=[NAME]` flag, i.e. `zig build -Dexample=assignment`. 149 | 150 | To see the full list of valid example names (in order by chapter) run `zig build --help`. 151 | 152 | Below is a demo of the default example: 153 | 154 |
155 | Example GIF 156 |
157 | 158 |

(back to top)

159 | 160 | 161 | 162 | 163 | ## Roadmap 164 | 165 | - [ ] Finish each chapter's examples ([#18](https://github.com/purefns/zig-bytes/issues/18)) 166 | - [ ] Finish adding OS support 167 | - [ ] Windows ([#2](https://github.com/purefns/zig-bytes/issues/2)) 168 | - [ ] FreeBSD ([#3](https://github.com/purefns/zig-bytes/issues/3)) 169 | - [ ] MacOS ([#4](https://github.com/purefns/zig-bytes/issues/4)) 170 | 171 | See the [open issues](https://github.com/purefns/zig-bytes/issues) for a full list of proposed features (and known issues). 172 | 173 |

(back to top)

174 | 175 | 176 | 177 | 178 | ## Contributing 179 | 180 | Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**. 181 | 182 | If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". 183 | Don't forget to give the project a star! Thanks again! 184 | 185 | 1. Fork the Project 186 | 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 187 | 3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 188 | 4. Push to the Branch (`git push origin feature/AmazingFeature`) 189 | 5. Open a Pull Request 190 | 191 |

(back to top)

192 | 193 | 194 | 195 | 196 | ## License 197 | 198 | Distributed under the MIT License. See `LICENSE` for more information. 199 | 200 |

(back to top)

201 | 202 | 203 | 204 | 205 | ## Contact 206 | 207 | James Adam - zigisgreat@proton.me 208 | 209 | Project Link: [https://github.com/purefns/zig-bytes](https://github.com/purefns/zig-bytes) 210 | 211 |

(back to top)

212 | 213 | 214 | 215 | 216 | ## Acknowledgments 217 | 218 | ❤️ [Ziglings](https://ziglings.org) for helping me figure out how to create a custom build step 219 | 220 | ❤️ [ZigHelp](https://zighelp.org/) for inspiration on the course layout 221 | 222 | ❤️ [Best README Template](https://github.com/othneildrew/Best-README-Template) for the amazing template 223 | 224 | 225 |

(back to top)

226 | 227 | 228 | 229 | 230 | 231 | [contributors-shield]: https://img.shields.io/github/contributors/purefns/zig-bytes.svg?style=for-the-badge 232 | [contributors-url]: https://github.com/purefns/zig-bytes/graphs/contributors 233 | [forks-shield]: https://img.shields.io/github/forks/purefns/zig-bytes.svg?style=for-the-badge 234 | [forks-url]: https://github.com/purefns/zig-bytes/network/members 235 | [stars-shield]: https://img.shields.io/github/stars/purefns/zig-bytes.svg?style=for-the-badge 236 | [stars-url]: https://github.com/purefns/zig-bytes/stargazers 237 | [issues-shield]: https://img.shields.io/github/issues/purefns/zig-bytes.svg?style=for-the-badge 238 | [issues-url]: https://github.com/purefns/zig-bytes/issues 239 | [license-shield]: https://img.shields.io/github/license/purefns/zig-bytes.svg?style=for-the-badge 240 | [license-url]: https://github.com/purefns/zig-bytes/blob/master/LICENSE 241 | [youtube-shield]: https://img.shields.io/badge/YouTube_Playlist-grey?style=for-the-badge&logo=youtube&logoColor=red 242 | [youtube-url]: https://youtube.com/playlist?list=PLlpKL2PE4xV-YPcbtiqQoO_kAPEF0Iumf&si=KtC_M7V4BDWVSz1n 243 | 244 | --------------------------------------------------------------------------------