Примеры
- Hello world
 - Вызов функций внешних библиотек
 - Обнаружение утечек памяти
 - Интероперабельность с C
 - Zigg Zagg
 - Обобщённые типы
 - Использование cURL из Zig
 
Hello world
A minimal example printing hello world.
const std = @import("std");
pub fn main() !void {
    try std.fs.File.stdout().writeAll("hello world!\n");
}$ zig build-exe hello-world.zig
$ ./hello-world
hello world!
Вызов функций внешних библиотек
Все функции системного API можно вызывать напрямую, без необходимости в дополнительных привязках.
const win = @import("std").os.windows;
extern "user32" fn MessageBoxA(?win.HWND, [*:0]const u8, [*:0]const u8, u32) callconv(win.WINAPI) i32;
pub fn main() !void {
    _ = MessageBoxA(null, "world!", "Hello", 0);
}$ zig test windows-msgbox.zig
All 0 tests passed.
Обнаружение утечек памяти
Используя std.heap.GeneralPurposeAllocator, можно отслеживать двойные освобождения и утечки памяти.
const std = @import("std");
pub fn main() !void {
    var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){};
    defer std.debug.assert(general_purpose_allocator.deinit() == .ok);
    const gpa = general_purpose_allocator.allocator();
    const u32_ptr = try gpa.create(u32);
    _ = u32_ptr; // silences unused variable error
    // oops I forgot to free!
}$ zig build-exe memory-leak.zig
$ ./memory-leak
error(gpa): memory address 0x7f5d08ea0000 leaked:
/home/ci/actions-runner-website/_work/www.ziglang.org/www.ziglang.org/zig-code/samples/memory-leak.zig:9:35: 0x113d457 in main (memory-leak.zig)
    const u32_ptr = try gpa.create(u32);
                                  ^
/home/ci/deps/zig-x86_64-linux-0.15.1/lib/std/start.zig:627:37: 0x113dd49 in posixCallMainAndExit (std.zig)
            const result = root.main() catch |err| {
                                    ^
/home/ci/deps/zig-x86_64-linux-0.15.1/lib/std/start.zig:232:5: 0x113d331 in _start (std.zig)
    asm volatile (switch (native_arch) {
    ^
thread 4088259 panic: reached unreachable code
/home/ci/deps/zig-x86_64-linux-0.15.1/lib/std/debug.zig:559:14: 0x1044179 in assert (std.zig)
    if (!ok) unreachable; // assertion failure
             ^
/home/ci/actions-runner-website/_work/www.ziglang.org/www.ziglang.org/zig-code/samples/memory-leak.zig:5:27: 0x113d526 in main (memory-leak.zig)
    defer std.debug.assert(general_purpose_allocator.deinit() == .ok);
                          ^
/home/ci/deps/zig-x86_64-linux-0.15.1/lib/std/start.zig:627:37: 0x113dd49 in posixCallMainAndExit (std.zig)
            const result = root.main() catch |err| {
                                    ^
/home/ci/deps/zig-x86_64-linux-0.15.1/lib/std/start.zig:232:5: 0x113d331 in _start (std.zig)
    asm volatile (switch (native_arch) {
    ^
???:?:?: 0x0 in ??? (???)
(process terminated by signal)
Интероперабельность с C
Пример импорта заголовочного файла C и связывания с libc и raylib.
// build with `zig build-exe c-interop.zig -lc -lraylib`
const ray = @cImport({
    @cInclude("raylib.h");
});
pub fn main() void {
    const screenWidth = 800;
    const screenHeight = 450;
    ray.InitWindow(screenWidth, screenHeight, "raylib [core] example - basic window");
    defer ray.CloseWindow();
    ray.SetTargetFPS(60);
    while (!ray.WindowShouldClose()) {
        ray.BeginDrawing();
        defer ray.EndDrawing();
        ray.ClearBackground(ray.RAYWHITE);
        ray.DrawText("Hello, World!", 190, 200, 20, ray.LIGHTGRAY);
    }
}
Zigg Zagg
Zig оптимизирован для собеседований по программированию (нет).
const std = @import("std");
pub fn main() !void {
    var i: usize = 1;
    while (i <= 16) : (i += 1) {
        if (i % 15 == 0) {
            std.log.info("ZiggZagg", .{});
        } else if (i % 3 == 0) {
            std.log.info("Zigg", .{});
        } else if (i % 5 == 0) {
            std.log.info("Zagg", .{});
        } else {
            std.log.info("{d}", .{i});
        }
    }
}$ zig build-exe ziggzagg.zig
$ ./ziggzagg
info: 1
info: 2
info: Zigg
info: 4
info: Zagg
info: Zigg
info: 7
info: 8
info: Zigg
info: Zagg
info: 11
info: Zigg
info: 13
info: 14
info: ZiggZagg
info: 16
Обобщённые типы
В языке Zig типы рассматриваются как значения на этапе компиляции. Мы используем функции, возвращающие типы, для реализации обобщённых алгоритмов и структур данных. В этом примере мы создаём простую обобщённую очередь и тестируем её работоспособность.
const std = @import("std");
pub fn Queue(comptime Child: type) type {
    return struct {
        const Self = @This();
        const Node = struct {
            data: Child,
            next: ?*Node,
        };
        gpa: std.mem.Allocator,
        start: ?*Node,
        end: ?*Node,
        pub fn init(gpa: std.mem.Allocator) Self {
            return Self{
                .gpa = gpa,
                .start = null,
                .end = null,
            };
        }
        pub fn enqueue(self: *Self, value: Child) !void {
            const node = try self.gpa.create(Node);
            node.* = .{ .data = value, .next = null };
            if (self.end) |end| end.next = node //
            else self.start = node;
            self.end = node;
        }
        pub fn dequeue(self: *Self) ?Child {
            const start = self.start orelse return null;
            defer self.gpa.destroy(start);
            if (start.next) |next|
                self.start = next
            else {
                self.start = null;
                self.end = null;
            }
            return start.data;
        }
    };
}
test "queue" {
    var int_queue = Queue(i32).init(std.testing.allocator);
    try int_queue.enqueue(25);
    try int_queue.enqueue(50);
    try int_queue.enqueue(75);
    try int_queue.enqueue(100);
    try std.testing.expectEqual(int_queue.dequeue(), 25);
    try std.testing.expectEqual(int_queue.dequeue(), 50);
    try std.testing.expectEqual(int_queue.dequeue(), 75);
    try std.testing.expectEqual(int_queue.dequeue(), 100);
    try std.testing.expectEqual(int_queue.dequeue(), null);
    try int_queue.enqueue(5);
    try std.testing.expectEqual(int_queue.dequeue(), 5);
    try std.testing.expectEqual(int_queue.dequeue(), null);
}$ zig test generic-type.zig
1/1 generic-type.test.queue...OK
All 1 tests passed.
Использование cURL из Zig
// compile with `zig build-exe zig-curl-test.zig --library curl --library c $(pkg-config --cflags libcurl)`
const std = @import("std");
const cURL = @cImport({
    @cInclude("curl/curl.h");
});
pub fn main() !void {
    var arena_state = std.heap.ArenaAllocator.init(std.heap.c_allocator);
    defer arena_state.deinit();
    const allocator = arena_state.allocator();
    // global curl init, or fail
    if (cURL.curl_global_init(cURL.CURL_GLOBAL_ALL) != cURL.CURLE_OK)
        return error.CURLGlobalInitFailed;
    defer cURL.curl_global_cleanup();
    // curl easy handle init, or fail
    const handle = cURL.curl_easy_init() orelse return error.CURLHandleInitFailed;
    defer cURL.curl_easy_cleanup(handle);
    var response_buffer = std.ArrayList(u8).init(allocator);
    // superfluous when using an arena allocator, but
    // important if the allocator implementation changes
    defer response_buffer.deinit();
    // setup curl options
    if (cURL.curl_easy_setopt(handle, cURL.CURLOPT_URL, "https://ziglang.org") != cURL.CURLE_OK)
        return error.CouldNotSetURL;
    // set write function callbacks
    if (cURL.curl_easy_setopt(handle, cURL.CURLOPT_WRITEFUNCTION, writeToArrayListCallback) != cURL.CURLE_OK)
        return error.CouldNotSetWriteCallback;
    if (cURL.curl_easy_setopt(handle, cURL.CURLOPT_WRITEDATA, &response_buffer) != cURL.CURLE_OK)
        return error.CouldNotSetWriteCallback;
    // perform
    if (cURL.curl_easy_perform(handle) != cURL.CURLE_OK)
        return error.FailedToPerformRequest;
    std.log.info("Got response of {d} bytes", .{response_buffer.items.len});
    std.debug.print("{s}\n", .{response_buffer.items});
}
fn writeToArrayListCallback(data: *anyopaque, size: c_uint, nmemb: c_uint, user_data: *anyopaque) callconv(.C) c_uint {
    var buffer: *std.ArrayList(u8) = @alignCast(@ptrCast(user_data));
    var typed_data: [*]u8 = @ptrCast(data);
    buffer.appendSlice(typed_data[0 .. nmemb * size]) catch return 0;
    return nmemb * size;
}