Zig Programming Language Documentation

website·Indexed 29 days ago

https://zig.hyperter.top

Documentation for Zig, a general-purpose system programming language and toolchain designed for robustness, optimality, and reusability. Covers core concepts including memory management, basic types, optional and union types, error handling, and data structures like arrays and slices. Includes guidance on the Zig build system, installation for Mac and Linux, and its use as a C/C++ compiler toolchain.

Tokens
6.9K
Snippets
46
Records
60
Agent score
50%

What's inside Zig

  1. Overview of Zig language features and design philosophy

    Zig is a low-level high-level language similar to C, designed to improve upon C's legacy issues while providing a robust toolchain and optional libc support. It emphasizes explicit declarations to improve code readability and is particularly suited for embedded development or high-performance applications where developers want to avoid the cognitive overhead of more complex high-level languages.

    Key technical features include:

    • Memory Management: Manual memory control with precise memory leak tracking at compile time.
    • Null Safety: Uses Optional types instead of null to prevent common memory errors.
    • Compilation & Execution: Supports compile-time execution (comptime) to implement generics and reflection.
    • C Integration: Direct C library integration without the need for FFI or bindings; the standard library integrates with libc but does not depend on it.
    • Tooling: First-class support for cross-compilation and a powerful build system that can be used as a toolchain for non-Zig (e.g., C) projects.
    • Runtime: Comprehensive stack traces, even on bare-metal hardware.
  2. Overview of the Zig programming language

    Zig is a general-purpose programming language and toolchain designed for maintaining robust, optimal, and reusable software. It focuses on simplicity and transparency by eliminating implicit control flow, implicit memory allocation, preprocessors, and macros.
  3. Overview of the Zig Toolchain

    Zig provides a comprehensive toolchain beyond the language itself. It includes zig cc and zig c++ for C and C++ compilation, and zig build as a unified build system suitable for Zig, C, and C++ projects.
    # C compiler
    zig cc
    
    # C++ compiler
    zig c++
    
    # Build system
    zig build
  4. Understand Zig's core design goals

    Zig is a systems programming language designed for simplicity, predictability, and efficiency. Its primary goals are:

    • Simplicity: A concise syntax and design philosophy that avoids complex features to lower the learning curve.
    • Predictability: Avoids implicit conversions and complex memory management found in many modern languages to ensure behavior is explicit.
    • Efficiency: Designed to compete with C and C++ by generating high-performance machine code while maintaining developer productivity.
  5. Declare and initialize arrays in Zig

    Arrays in Zig are contiguous blocks of memory with a fixed length and elements of the same type. You can specify the length explicitly or use _ to let the compiler infer the length from the literal values. Array indices start at 0, and Zig provides bounds checking at both compile-time and runtime.
    const message = [5]u8{ 'h', 'e', 'l', 'l', 'o' };
    // Or let the compiler infer length:
    const message_inferred = [_]u8{ 'h', 'e', 'l', 'l', 'o' };
  6. Destructure Optional and Error Union types in while loops

    A while loop can destructure an optional type, continuing until null is encountered. Similarly, it can destructure an error union, continuing until an error occurs, at which point it executes the else |err| block and terminates.
    // Optional destructuring: loops until null
    while (eventuallyNullSequence()) |value| {
        sum += value;
    } else {
        std.debug.print("meet a null\n", .{});
    }
    
    // Error Union destructuring: loops until error
    while (eventuallyErrorSequence()) |value| {
        sum += value;
    } else |err| {
        std.debug.print("meet a err: {}\n", .{err});
    }
  7. Use while loops and continue expressions

    The while loop repeats as long as a condition is true. Zig provides a continue expression syntax : (expression) to execute code at the end of every iteration, which is useful for incrementing counters.
    var i: usize = 0;
    while (i < 10) : (i += 1) {
        if (i == 5) continue;
        std.debug.print("i is {}\n", .{i});
    }
    
    // Multi-statement continue expression
    var j: usize = 1;
    while (i * j < 2000) : ({ i *= 2; j *= 3; }) {}
  8. Handle strings and multi-line literals in Zig

    Strings in Zig are assumed to be UTF-8 encoded. Non-ASCII bytes can be inserted using \xNN escapes. For multi-line strings, use the \ prefix on each line; these strings do not support escapes, and the final newline is not included in the string.
    // Multi-line string literal
    const hello_world_in_c = 
    \#include <stdio.h>
    \
    \int main(int argc, char **argv) {
    \    printf("hello world\n");
    \    return 0;
    \}
    ;
  9. Use conditional statements and ternary expressions in Zig

    Zig uses if, else if, and else for basic conditional logic. Additionally, Zig implements ternary expressions using the if (condition) value_if_true else value_if_false syntax, which can be used to assign values to constants.
    const num: u8 = 1;
    if (num == 1) {
        std.debug.print("num is 1\n", .{});
    } else if (num == 2) {
        std.debug.print("num is 2\n", .{});
    } else {
        std.debug.print("num is other\n", .{});
    }
    
    // Ternary expression
    const a: u32 = 5;
    const b: u32 = 4;
    const result = if (a != b) 47 else 3089;
  10. Destructure Error Union types using if

    Error union types are destructured using if (union_val) |value| for the success path and else |err| to capture the error. If the type is an Error Optional Union (anyerror!?T), if first destructures the error union, then the optional type.
    const val: anyerror!u32 = 0;
    if (val) |value| {
        // value is u32
    } else |err| {
        // err is anyerror
    }
    
    // Error Optional Union
    const a: anyerror!?u32 = 0;
    if (a) |optional_value| {
        // optional_value is ?u32
        if (optional_value) |final_val| {
            _ = final_val;
        }
    } else |err| {
        _ = err;
    }
  11. Iterate over arrays, slices, and ranges with for

    The for loop is used for iterating over arrays, slices, or ranges. It supports value capture (read-only) and pointer capture (for modification). You can also iterate over indices by adding 0.. to the loop expression or iterate over multiple arrays of the same length simultaneously.
    const items = [_]i32{ 4, 5, 3 };
    
    // Value capture (read-only)
    for (items) |value| {
        _ = value;
    }
    
    // Pointer capture (mutable)
    var mutable_items = [_]i32{ 3, 4, 2 };
    for (&mutable_items) |*value| {
        value.* += 1;
    }
    
    // Range iteration
    for (0..5) |i| {
        _ = i;
    }
    
    // Iterating with indices
    for (items, 0..) |value, i| {
        _ = value;
        _ = i;
    }
    
    // Multi-objective iteration
    const items2 = [_]usize{ 4, 5, 6 };
    for (items, items2) |i, j| {
        _ = i;
        _ = j;
    }