Appendix A. Zig Syntax Summary
This appendix summarizes the core syntax of Zig 0.16. It is a compact reference, not a tutorial.
Appendix A. Zig Syntax Summary
This appendix summarizes the core syntax of Zig 0.16. It is a compact reference, not a tutorial.
A.1 Comments
Single-line comments begin with //.
// this is a comment
Documentation comments begin with ///.
/// add two integers
fn add(a: i32, b: i32) i32 {
return a + b;
}
Container-level documentation comments begin with //!.
//! small utility library
A.2 Declarations
Variables use var.
var count: i32 = 10;
Constants use const.
const limit = 100;
Type annotations are optional when the compiler can infer the type.
const name = "zig";
A.3 Primitive Types
| Type | Meaning |
|---|---|
i32 |
signed 32-bit integer |
u64 |
unsigned 64-bit integer |
f32 |
32-bit float |
bool |
boolean |
usize |
pointer-sized unsigned integer |
isize |
pointer-sized signed integer |
void |
no value |
noreturn |
expression never returns |
A.4 Integer Literals
const a = 123;
const b = 0xff;
const c = 0b1010;
const d = 0o755;
Underscores improve readability.
const million = 1_000_000;
A.5 Strings
Strings are byte slices.
const text = "hello";
String type:
[]const u8
Multiline strings use escaping.
const text =
\\hello
\\zig
;
A.6 Arrays and Slices
Fixed-size array:
const values = [4]i32{ 1, 2, 3, 4 };
Slice:
const part = values[1..3];
Array length:
values.len
A.7 Pointers
Single-item pointer:
var value: i32 = 10;
const ptr: *i32 = &value;
Dereference:
ptr.*
Pointer assignment:
ptr.* = 20;
Many-item pointer:
[*]u8
Optional pointer:
?*i32
A.8 Functions
Function declaration:
fn add(a: i32, b: i32) i32 {
return a + b;
}
Public function:
pub fn main() void {}
Error-returning function:
fn parse(text: []const u8) !i32 {
...
}
Generic function:
fn identity(value: anytype) @TypeOf(value) {
return value;
}
A.9 Blocks and Scope
Blocks introduce scope.
{
const x = 10;
}
Blocks are expressions.
const n = blk: {
break :blk 42;
};
A.10 Control Flow
if expression:
if (x > 0) {
...
} else {
...
}
switch expression:
switch (value) {
0 => {},
1 => {},
else => {},
}
while loop:
while (n < 10) : (n += 1) {
...
}
for loop:
for (items) |item| {
...
}
A.11 Optionals
Optional type:
?i32
Null value:
null
Unwrapping:
const value = maybe orelse 0;
Optional capture:
if (maybe) |value| {
...
}
A.12 Errors
Error set:
const ParseError = error{
Invalid,
Overflow,
};
Error union:
ParseError!i32
Propagate error:
const n = try parse(text);
Handle error:
parse(text) catch 0;
A.13 Defer
defer runs at scope exit.
defer file.close();
errdefer runs only on error.
errdefer allocator.free(buffer);
A.14 Structs
Struct declaration:
const Point = struct {
x: i32,
y: i32,
};
Initialization:
const p = Point{
.x = 10,
.y = 20,
};
Method:
const Counter = struct {
value: i32,
pub fn inc(self: *Counter) void {
self.value += 1;
}
};
A.15 Enums
const Color = enum {
red,
green,
blue,
};
A.16 Unions
Tagged union:
const Value = union(enum) {
int: i32,
float: f64,
};
Switch on union:
switch (value) {
.int => |n| {},
.float => |x| {},
}
A.17 Allocators
Allocation:
const memory = try allocator.alloc(u8, 1024);
Free memory:
allocator.free(memory);
A.18 Testing
Test block:
test "addition" {
try std.testing.expect(1 + 1 == 2);
}
Run tests:
zig test main.zig
A.19 Imports
Import standard library:
const std = @import("std");
Import source file:
const math = @import("math.zig");
A.20 Builtin Functions
Builtin functions begin with @.
@TypeOf(x)
@sizeOf(i32)
@intCast(value)
@ptrCast(ptr)
@memcpy(dst, src)
A.21 Formatting
Print formatted text:
std.debug.print("value = {d}\n", .{n});
Common format specifiers:
| Specifier | Meaning |
|---|---|
{d} |
decimal integer |
{x} |
hexadecimal |
{b} |
binary |
{s} |
string |
{any} |
generic formatting |
A.22 Build Commands
| Command | Meaning |
|---|---|
zig run main.zig |
build and run |
zig build-exe main.zig |
build executable |
zig test main.zig |
run tests |
zig build |
run build script |
zig fmt file.zig |
format source |
A.23 File Structure
Typical project layout:
project/
build.zig
build.zig.zon
src/
main.zig