Skip to content

Latest commit

 

History

History
233 lines (162 loc) · 8.26 KB

ch-07-primitive-types.md

File metadata and controls

233 lines (162 loc) · 8.26 KB

Примитивные типы в языке Zig: Обзор и возможности

Примитивные типы данных являются основой любого языка программирования, и Zig не исключение. Они предоставляют базовые строительные блоки для работы с числами, символами, булевыми значениями, указателями и другими элементарными данными. Zig, как язык системного программирования, разработанный с упором на производительность и контроль, предоставляет широкий набор примитивных типов, обеспечивая разработчикам гибкость и точность.


Категории примитивных типов в Zig

В Zig примитивные типы можно разделить на несколько категорий:

  1. Числовые типы:

    • Целые числа (знаковые и беззнаковые).
    • Числа с плавающей запятой.
    • Фиксированные размеры чисел.
  2. Символьные типы:

    • Один символ (кодовая точка Unicode).
  3. Логический тип:

    • Булевое значение.
  4. Указатели и ссылки:

    • Прямое управление памятью.
  5. Другие встроенные типы:

    • Срезы, массивы, массивы фиксированной длины, кортежи.

1. Целочисленные типы

Целые числа в Zig представлены с фиксированным размером и могут быть знаковыми (iN) или беззнаковыми (uN), где N — размер в битах (например, i8, u64).

Пример:

const std = @import("std");

pub fn main() void {
    var a: i32 = -42;
    var b: u64 = 123456789;

    std.debug.print("a: {}, b: {}\n", .{a, b});
}

Размеры целых чисел:

  • Знаковые: i8, i16, i32, i64, i128.
  • Беззнаковые: u8, u16, u32, u64, u128.

Особенности:

  • Компилятор Zig гарантирует отсутствие переполнений по умолчанию. Если переполнение возможно, оно вызывает ошибку времени выполнения или компиляции.
  • Для отключения проверки переполнений можно использовать специальные операции, например +%.

2. Числа с плавающей запятой

Zig поддерживает стандартные типы чисел с плавающей запятой: f16, f32, f64 и f128.

Пример:

pub fn main() void {
    var pi: f64 = 3.141592653589793;
    var small: f32 = 0.0001;

    std.debug.print("pi: {}, small: {}\n", .{pi, small});
}

Особенности:

  • Поддержка арифметики IEEE 754.
  • Возможность работы с бесконечностями и NaN.

3. Логический тип

Булевый тип представлен как bool и может принимать значения true или false.

Пример:

pub fn main() void {
    var is_valid: bool = true;

    if (is_valid) {
        std.debug.print("Данные валидны.\n", .{});
    } else {
        std.debug.print("Данные не валидны.\n", .{});
    }
}

Особенности:

  • Используется для условий, циклов и логических операций.
  • Размер булевого значения составляет 1 байт.

4. Символьный тип

Zig поддерживает тип u8 для работы с ASCII-символами и u21 для кодовых точек Unicode.

Пример:

pub fn main() void {
    const char: u8 = 'A';
    const emoji: u21 = '😊';

    std.debug.print("Символ: {}, Emoji: {}\n", .{char, emoji});
}

Особенности:

  • Символы — это числовые представления.
  • Работа с Unicode требует понимания кодировок.

5. Указатели и ссылки

Указатели (*T) — важный инструмент в Zig, позволяющий напрямую работать с памятью.

Пример:

pub fn main() void {
    var x: i32 = 42;
    var ptr: *i32 = &x;

    std.debug.print("Значение через указатель: {}\n", .{ptr.*});
}

Особенности:

  • Указатели могут быть безопасными или небезопасными (в зависимости от контекста).
  • Zig поддерживает null-указатели, но требует явной проверки.

6. Срезы

Срезы ([]T) позволяют работать с массивами без создания копий.

Пример:

pub fn main() void {
    var array: [5]u32 = [5]u32{10, 20, 30, 40, 50};
    const slice = array[1..4];

    for (slice) |value| {
        std.debug.print("{}\n", .{value});
    }
}

Особенности:

  • Срезы сохраняют ссылку на оригинальные данные.
  • Используются для работы с массивами переменной длины.

7. Анонимные типы

Zig поддерживает типы, определённые на месте, такие как кортежи и структуры.

Пример кортежа:

pub fn main() void {
    const tuple = .{42, "hello", true};

    std.debug.print("Число: {}, Строка: {}, Булево: {}\n", .{tuple.0, tuple.1, tuple.2});
}

Пример структуры:

const std = @import("std");

pub fn main() void {
    const point = struct {
        x: i32,
        y: i32,
    }{ .x = 10, .y = 20 };

    std.debug.print("Point: ({}, {})\n", .{point.x, point.y});
}

8. Управление памятью

В Zig примитивные типы тесно связаны с управлением памятью. Выделение и освобождение памяти осуществляется вручную через аллокаторы, что позволяет избегать утечек памяти.

Пример выделения памяти для массива:

const std = @import("std");

pub fn main() !void {
    const allocator = std.heap.page_allocator;

    var buffer = try allocator.alloc(u8, 10);
    defer allocator.free(buffer);

    for (buffer) |*value, index| {
        value.* = @as(u8, index);
    }

    std.debug.print("Массив: {}\n", .{buffer});
}

9. Работа с константами

Константы в Zig объявляются с использованием ключевого слова const. Они могут быть вычислены на этапе компиляции, что позволяет оптимизировать код.

Пример:

const PI: f64 = 3.141592653589793;
const RADIUS: u32 = 5;
const AREA: f64 = @mul(@pow(PI, 2), @as(f64, RADIUS));

pub fn main() void {
    std.debug.print("Площадь круга: {}\n", .{AREA});
}

Заключение

Примитивные типы в Zig — это мощный инструмент, который сочетается с низкоуровневым управлением памятью и производительностью. Разработчики получают точный контроль над размерами, представлением и поведением данных, что делает Zig идеальным для системного программирования и задач, требующих высокой эффективности.