Функции Zig

Функции — важный инструмент в языках программирования для организации кода и реализации логики.

Функции — важный инструмент для организации кода. Правильное использование функций может улучшить читаемость и возможность повторного использования кода.

В реальном программировании вы можете определять различные функции по мере необходимости для реализации конкретных возможностей.

Функции Zig определяются с помощью ключевого словаfn.

Базовый синтаксис

В Zig базовый синтаксис определения функции выглядит следующим образом:

fn 函数名(参数列表) 返回类型 {
    // 函数体
}

Например, определим простую функцию printHello, которая выводит "Hello, World!":

Пример

const std = @import("std");

pub fn main() void {
    printHello();
}

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

Вывод после компиляции:

Hello, World!

Передача параметров

Функции могут принимать параметры, которые могут быть значениями различных типов.

Параметры перечисляются при определении функции и передаются в функцию при её вызове, например:

Пример

const std = @import("std");

pub fn main() void {
    greet("Alice");
}

fn greet(name: []const u8) void {
    std.debug.print("Hello, {s}!\n", .{name}); // Используйте спецификатор формата {s} для вывода среза строки
}

Вывод после компиляции:

Hello, Alice!

Возвращаемые значения

Функции могут возвращать значения. Тип возвращаемого значения указывается в определении функции с помощью ключевого словаreturn.

Например, определите функцию, которая вычисляет сумму двух целых чисел:

Пример

const std = @import("std");

pub fn main() void {
    const result = add(3, 5);
    std.debug.print("3 + 5 = {}\n", .{result});
}

fn add(a: i32, b: i32) i32 {
    return a + b;
}

Вывод после компиляции:

3 + 5 = 8

Рекурсия

Функции могут вызывать сами себя, что называется рекурсивным вызовом.

Например, определите рекурсивную функцию, которая вычисляет факториал:

Пример

const std = @import("std");

pub fn main() void {
    const result = factorial(5);
    std.debug.print("5! = {}\n", .{result});
}

fn factorial(n: i32) i32 {
    if (n == 0) {
        return 1;
    } else {
        return n * factorial(n - 1);
    }
}

Вывод после компиляции:

5! = 120

Перегрузка функций

Zig не поддерживает перегрузку функций в традиционном смысле (то есть несколько функций с одинаковым именем, но разными параметрами).

Zig предоставляет функциональность обобщённых функций. Используя параметры, известные на этапе компиляции, можно достичь эффектов, похожих на перегрузку функций, например:

Пример

const std = @import("std");

pub fn main() void {
    printValue(i32, 5); // Явно указать тип как i32
    printValue([]const u8, "Hello"); // Явно указать тип как []const u8
}

fn printValue(comptime T: type, value: T) void {
    std.debug.print("{any}\n", .{value}); // Используйте {any} для обработки значений разных типов
}

В этом примере функция printValue может принимать параметры любого типа и выводить их в зависимости от типа параметра.

Вывод после компиляции:

5
{ 72, 101, 108, 108, 111 }

Встроенные функции

Встроенная функция означает, что код функции непосредственно вставляется в место вызова во время компиляции, благодаря чему избегаются накладные расходы на вызов функции.

В Zig можно использовать ключевое словоinlineдля определения встроенных функций, например:

Пример

const std = @import("std");

// Определить встроенную функцию
inline fn square(x: i32) i32 {
    return x * x;
}

pub fn main() void {
    const result = square(5); // Вставить код встроенной функции в месте вызова
    std.debug.print("Квадрат 5 равен {}\n", .{result});
}

В этом примере функция square определена как inline-функция, и компилятор вставит её код непосредственно в месте вызова.

Вывод после компиляции:

Square of 5 is 25
Другие расширения