Skip to content

Zig Basic Syntax

This chapter introduces the basic syntax rules of the Zig language, laying a solid foundation for subsequent learning.

Program Structure

The Simplest Zig Program

zig
const std = @import("std");

pub fn main() void {
    std.debug.print("Hello, World!\n", .{});
}

Let's analyze each part of this program:

  • const std = @import("std"); - Import the standard library
  • pub fn main() void - Define a public main function with void return type
  • std.debug.print() - Call the standard library's print function
  • .{} - Empty parameter tuple

Comments

Single-line Comments

zig
// This is a single-line comment
const x = 42; // End-of-line comment

Documentation Comments

zig
/// This is a documentation comment, used for generating documentation
/// Can span multiple lines
pub fn add(a: i32, b: i32) i32 {
    return a + b;
}

Top-level Documentation Comments

zig
//! This is a top-level documentation comment
//! Used to describe the entire file or module

Identifiers

Naming Rules

  • Start with a letter or underscore
  • Can contain letters, numbers, underscores
  • Case-sensitive
zig
const valid_name = 1;
const ValidName = 2;
const _private = 3;
const name123 = 4;

Naming Conventions

zig
// Variables and functions: snake_case
const my_variable = 42;
fn my_function() void {}

// Types: PascalCase
const MyStruct = struct {};
const MyEnum = enum {};

// Constants: SCREAMING_SNAKE_CASE
const MAX_SIZE = 1024;

Keywords

Zig keywords cannot be used as identifiers:

zig
// Control flow
if, else, switch, while, for, break, continue, return

// Type-related
struct, enum, union, fn, var, const, comptime

// Error handling
try, catch, error, defer, errdefer

// Others
pub, export, extern, inline, noinline, packed, align
and, or, null, undefined, unreachable, async, await, suspend, resume

Statements and Expressions

Statements

Statements perform operations but don't return values:

zig
const x = 42;        // Declaration statement
var y: i32 = 10;     // Declaration statement
y = 20;              // Assignment statement

Expressions

Expressions evaluate and return values:

zig
const sum = 1 + 2;           // Arithmetic expression
const is_equal = x == y;     // Comparison expression
const result = if (x > 0) 1 else 0;  // Conditional expression

Semicolon Rules

Semicolons are optional in Zig, but there are specific rules:

zig
// Cases where semicolons are not needed
const x = 42
const y = 24

// Cases where semicolons are needed (multiple statements on same line)
const a = 1; const b = 2;

// Usually no semicolon needed after function calls
std.debug.print("Hello\n", .{})

Code Blocks

Use curly braces {} to define code blocks:

zig
pub fn main() void {
    // This is a code block
    const x = 42;

    if (x > 0) {
        // This is another code block
        std.debug.print("Positive\n", .{});
    }
}

Operators

Arithmetic Operators

zig
const a = 10;
const b = 3;

const sum = a + b;      // Addition: 13
const diff = a - b;     // Subtraction: 7
const product = a * b;  // Multiplication: 30
const quotient = a / b; // Division: 3
const remainder = a % b; // Modulus: 1

Comparison Operators

zig
const x = 10;
const y = 20;

const equal = x == y;        // Equal: false
const not_equal = x != y;    // Not equal: true
const less = x < y;          // Less than: true
const less_equal = x <= y;   // Less than or equal: true
const greater = x > y;       // Greater than: false
const greater_equal = x >= y; // Greater than or equal: false

Logical Operators

zig
const a = true;
const b = false;

const and_result = a and b;  // Logical AND: false
const or_result = a or b;    // Logical OR: true
const not_result = !a;       // Logical NOT: false

Bitwise Operators

zig
const x: u8 = 0b1010; // 10
const y: u8 = 0b1100; // 12

const and_bits = x & y;   // Bitwise AND: 0b1000 (8)
const or_bits = x | y;    // Bitwise OR: 0b1110 (14)
const xor_bits = x ^ y;   // Bitwise XOR: 0b0110 (6)
const not_bits = ~x;      // Bitwise NOT: 0b11110101 (245)
const left_shift = x << 1; // Left shift: 0b10100 (20)
const right_shift = x >> 1; // Right shift: 0b0101 (5)

Literals

Integer Literals

zig
const decimal = 42;          // Decimal
const binary = 0b101010;     // Binary
const octal = 0o52;          // Octal
const hex = 0x2A;            // Hexadecimal
const with_underscores = 1_000_000; // Using underscores as separators

Float Literals

zig
const float1 = 3.14;         // Regular float
const float2 = 1.23e-4;      // Scientific notation
const float3 = 0x1.fp+1023;  // Hexadecimal float

Character Literals

zig
const char = 'A';            // Character literal
const unicode = '中';        // Unicode character
const escape = '\n';         // Escape character

String Literals

zig
const string = "Hello, World!";
const multiline =
    \\This is a
    \\multiline string
    \\using \\ prefix
;
const unicode_string = "你好,世界!";

Escape Sequences

zig
const newline = '\n';        // Newline
const tab = '\t';            // Tab
const carriage_return = '\r'; // Carriage return
const backslash = '\\';      // Backslash
const quote = '\'';          // Single quote
const double_quote = '\"';   // Double quote
const null_char = '\0';      // Null character
const unicode = '\u{1F600}'; // Unicode escape

Array and Slice Literals

zig
// Array literal
const array = [_]i32{1, 2, 3, 4, 5};
const explicit_array = [5]i32{1, 2, 3, 4, 5};

// String slice
const slice: []const u8 = "Hello";

Struct Literals

zig
const Point = struct {
    x: f32,
    y: f32,
};

const point = Point{
    .x = 1.0,
    .y = 2.0,
};

// Simplified syntax (field names match variable names)
const x: f32 = 1.0;
const y: f32 = 2.0;
const point2 = Point{ x, y };

Function Call Syntax

zig
// Basic function call
const result = add(1, 2);

// Method call syntax
const string = "hello";
const length = string.len;

// Chained calls
const processed = data.filter().map().collect();

Error Handling Syntax

zig
// try expression
const file = try std.fs.cwd().openFile("data.txt", .{});

// catch expression
const value = parseNumber(input) catch 0;

// if error handling
if (parseNumber(input)) |num| {
    // Success case
    std.debug.print("Number: {}\n", .{num});
} else |err| {
    // Error case
    std.debug.print("Error: {}\n", .{err});
}

Optional Type Syntax

zig
var maybe_number: ?i32 = null;
maybe_number = 42;

// if optional handling
if (maybe_number) |number| {
    std.debug.print("Number: {}\n", .{number});
} else {
    std.debug.print("No number\n", .{});
}

// orelse operator
const number = maybe_number orelse 0;

Compile-time Syntax

zig
// comptime keyword
comptime var compile_time_var = 42;

// Compile-time function call
const result = comptime fibonacci(10);

// Compile-time condition
const is_debug = comptime std.debug.runtime_safety;

Code Example: Comprehensive Syntax Demonstration

zig
const std = @import("std");

/// Calculate the sum of two numbers
pub fn add(a: i32, b: i32) i32 {
    return a + b;
}

/// Main function
pub fn main() void {
    // Variable declarations
    const x = 10;
    var y: i32 = 20;

    // Arithmetic operations
    const sum = add(x, y);
    const product = x * y;

    // Conditional expression
    const max = if (x > y) x else y;

    // String handling
    const message = "Calculation Results";

    // Output results
    std.debug.print("{}:\n", .{message});
    std.debug.print("Sum: {}\n", .{sum});
    std.debug.print("Product: {}\n", .{product});
    std.debug.print("Max: {}\n", .{max});

    // Loop
    var i: i32 = 0;
    while (i < 3) : (i += 1) {
        std.debug.print("Loop iteration {}\n", .{i});
    }
}

Syntax Best Practices

1. Maintain Consistent Indentation

zig
// Good practice
if (condition) {
    doSomething();
    doAnotherThing();
}

// Avoid
if (condition) {
doSomething();
    doAnotherThing();
}

2. Reasonable Use of Blank Lines

zig
const std = @import("std");

pub fn main() void {
    const x = 42;
    const y = 24;

    const sum = x + y;

    std.debug.print("Sum: {}\n", .{sum});
}

3. Appropriate Comments

zig
// Explain complex logic
const hash = computeHash(data); // Using FNV-1a algorithm

/// Public APIs need documentation comments
pub fn processData(input: []const u8) ![]u8 {
    // Implementation details...
}

Summary

This chapter introduced Zig's basic syntax rules, including:

  • ✅ Program structure and comments
  • ✅ Identifiers and keywords
  • ✅ Operators and literals
  • ✅ Basic syntax structures
  • ✅ Code style recommendations

After mastering these basic syntax elements, you can start writing simple Zig programs. In the next chapter, we'll learn about variable declarations in Zig.

Content is for learning and research only.