Базовый синтаксис Zig
Zig — это новый язык программирования, простой и эффективный по дизайну, напрямую совместимый с языком C.
Ниже представлено введение в некоторые основы синтаксиса Zig, которые помогут вам быстро начать.
Расширение файлов с кодом Zig —.zig。
Первая программа на Zig
Давайте сначала посмотрим на программу "Hello, World!" на Zig.
Давайте сначала инициализируем проект zig:
mkdir hello-world cd hello-world zig init
Затем создайте файл hello.zig в этом проекте со следующим кодом:
Пример (файл hello.zig)
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
try stdout.print("Hello, World!\n", .{});
}
Анализ кода:
1. Импорт стандартной библиотеки:
const std = @import("std");
Эта строка кода импортирует стандартную библиотеку Zig, аналогично в языке C.#include <stdio.h>。
2. Определите функцию main:
pub fn main() !void
pubКлючевое слово указывает, что эта функция является публичной,fnКлючевое слово используется для определения функции,mainявляется точкой входа функции. Тип возвращаемого значения!voidуказывает, что функция не возвращает значение, но может вернуть ошибку (!префикс указывает на тип объединения с ошибкой).
3. Получение стандартного вывода:
const stdout = std.io.getStdOut().writer();
Получите writer стандартного вывода через стандартную библиотеку, затем вызовите его методы для записи содержимого.
4. Напечатайте "Hello, World!":
try stdout.print("Hello, World!\n", .{});
printМетод записывает форматированную строку в стандартный вывод,.{}является пустым списком параметров.tryКлючевое слово передаёт ошибки наверх вызывающему при возникновении ошибки.
Эта программа демонстрирует некоторые базовые возможности языка Zig, такие как определение функций, использование стандартной библиотеки и обработка ошибок.
Если вы просто хотите запустить один файл, можно сразу использовать:
zig run hello.zig
Если вы хотите скомпилировать его в исполняемый файл, используйте:
zig build-exe hello.zig
После компиляции запустите его в терминале:
./hello
Это выведет:
Hello, World!
Идентификаторы
В Zig идентификаторы — это имена, используемые для именования переменных, функций, типов и так далее.
Вот некоторые правила и особенности, касающиеся идентификаторов Zig:
-
Буквы и цифры: Идентификаторы могут содержать буквы (A-Z и a-z), цифры (0-9) и символы подчеркивания (_).
-
Начальный символ: Идентификаторы должны начинаться с буквы или символа подчеркивания и не могут начинаться с цифры.
-
Чувствительность к регистру: Zig — регистрозависимый язык, что означает
Variableиvariable— это два разных идентификатора. -
Ключевые и зарезервированные слова: Некоторые конкретные слова зарезервированы в Zig и не могут использоваться в качестве идентификаторов. Например,
fn(функция),struct(struct),if(условный оператор) и т. д. -
Соглашения об именовании: Zig официально рекомендует следующие соглашения:
- camelCase: Используется для имён переменных и имён функций. Например,
myVariable、calculateSum。 - PascalCase: Используется для имён типов и пространств имён. Например,
Point、ArrayList。 - SCREAMING_SNAKE_CASE: Используется для констант, известных во время компиляции (comptime-констант). Например,
MAX_SIZE。
- camelCase: Используется для имён переменных и имён функций. Например,
-
Опциональный тип: В Zig есть специальный тип
?T, который представляет опциональное значение типаT. Это очень полезно при работе со значениями, которые могут быть null. -
Константы времени компиляции: Используя
comptimeключевое слово перед идентификатором указывает, что идентификатор является константой времени компиляции. -
Типы ошибок: Используя
errorключевое слово определяет типы ошибок, например:pub fn openFile(path: []const u8) !void { // ... } -
Суффикс типа: Добавление
_tсуффикса после имён типов — это привычка языка C; в Zig можно делать то же самое, но это не обязательно.
Зарезервированные ключевые слова
Ниже приведены некоторые зарезервированные ключевые слова в Zig:
| Ключевые слова | Описание |
|---|---|
align | Задаёт количество байтов выравнивания для переменной или типа |
allowzero | Позволяет указателям указывать на null |
and | Логическая операция И |
asm | Блок встроенного ассемблера |
break | Выход из ближайшего цикла или области видимости |
callconv | Соглашение о вызове |
const | Определяет константу |
continue | Перейти к следующей итерации цикла |
defer | Отложить выполнение оператора до выхода из области видимости |
else | Отрицательная ветвь условного оператора |
enum | Тип перечисления |
errdefer | Оператор отложенного выполнения при возникновении ошибки |
error | Определение типа ошибки |
export | Экспорт символов для использования языком C и т. п. |
fn | Определение функции |
for | Цикл обхода |
if | Условный оператор |
inline | Встроенная функция или встроенный цикл |
linksection | Указывает секцию компоновщика |
noalias | Другие указатели не могут быть псевдонимами этого указателя |
noinline | Запретить встраивание функций |
null | Значение null для опциональных типов |
or | Логическая операция ИЛИ |
packed | Удаляет выравнивание структуры, обеспечивая плотную побитовую упаковку |
pub | Публичный уровень доступа |
return | Возврат из функции |
struct | Определение типа структуры |
switch | Оператор выбора с несколькими ветвями |
test | Блок тестового кода |
threadlocal | Переменная, локальная для потока |
try | Попытаться выполнить выражение, распространяя ошибки вверх при сбое |
union | Определение union-типа |
usingnamespace | Внести все публичные члены пространства имён в текущую область видимости |
var | Определить изменяемую переменную |
void | Нет типа, часто используется, когда функция не возвращает значение |
while | Оператор цикла |
Базовый синтаксис
1. Переменные и константы
В Zig переменные используютvarключевое слово для определения, константы используютconstключевое слово для определения.
const x: i32 = 10; // 定义一个整数常量 x,值为 10 var y: f64 = 3.14; // 定义一个浮点数变量 y,值为 3.14
2. Функции
Функции используютfnключевое слово для определения и указывают возвращаемый тип.
const std = @import("std");
fn add(a: i32, b: i32) i32 {
return a + b;
}
pub fn main() !void {
const result = add(3, 4);
const stdout = std.io.getStdOut().writer();
try stdout.print("Result: {}\n", .{result});
}
3. Условные операторы
Используйтеifиelseдля реализации условной логики.
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
const number = 10;
if (number > 0) {
try stdout.print("Number is positive\n", .{});
} else {
try stdout.print("Number is not positive\n", .{});
}
}
4. Циклы
Zig поддерживаетwhileиforциклах.
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
// while 循环,: (i += 1) 是每次迭代后执行的更新表达式
var i: i32 = 0;
while (i < 5) : (i += 1) {
try stdout.print("i: {}\n", .{i});
}
// for 循环,遍历数组
const array = [5]i32{ 1, 2, 3, 4, 5 };
for (array) |item| {
try stdout.print("item: {}\n", .{item});
}
}
5. Структуры
Zig используетstructдля определения структур.
const std = @import("std");
const Point = struct {
x: i32,
y: i32,
};
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
const p = Point{ .x = 10, .y = 20 };
try stdout.print("Point: ({}, {})\n", .{ p.x, p.y });
}
6. Обработка ошибок
Zig использует типы перечислений ошибок иtry / catchключевое слово для обработки ошибок.
const std = @import("std");
const FileError = error{
FileNotFound,
};
fn readFile(path: []const u8) !void {
// 模拟一个可能失败的操作
if (std.mem.eql(u8, path, "invalid")) {
return FileError.FileNotFound;
}
// 其他操作...
}
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
readFile("invalid") catch |err| {
switch (err) {
FileError.FileNotFound => {
try stdout.print("Error: File not found\n", .{});
},
else => return err,
}
return;
};
try stdout.print("File read successfully\n", .{});
}
Анализ кода:
catch |err|: Перехватить ошибку и привязать её к переменнойerr。switch (err): Сопоставить тип ошибки и обрабатывать разные случаи ошибок отдельно.else => return err: Пробрасывать непредвиденные ошибки напрямую вверх, не игнорируя их молча.- Если
readFileвыполняется успешно (без срабатывания catch), затем продолжается выполнение следующего оператора print.