On branch main

modified:   src/ch01.md
This commit is contained in:
zed
2023-11-09 23:24:16 +03:00
parent 0ca97bdbc4
commit 35b4827a2a

View File

@@ -57,7 +57,7 @@ zig run ex-ch01-01.zig
При импортировании модуля нужно указать его имя. Стандартная библиотека Zig доступна
по имени `std`. Чтобы импортировать какой-то конкретный файл, нужно использовать
путь относительно того файла, в котором делается имортирование. Например, мы могли
путь относительно того файла, в котором делается импортирование. Например, мы могли
бы поместить описание структуры `User` в отдельный файл (скажем, `models/user.zig`)
и тогда бы в основном файле мы бы написали
@@ -81,7 +81,7 @@ pub const User = struct {
};
```
И тогда бы могли в главном файле имортировать обе сущности:
И тогда бы могли в главном файле импортировать обе сущности:
```
const user = @import("models/user.zig");
@@ -91,11 +91,11 @@ const MAX_POWER = user.MAX_POWER;
Скорее всего, на данный момент у Вас больше вопросов, чем ответов.
Что такое `user` в приведенном отрывке? Хотя мы ещё не знакомы с ключевым
словом `var`, но тем не менее можно спросить, а что если вместо `const`
словом `var`, но тем не менее можно спросить, а что, если вместо `const`
использовать `var`? Или. возможно, у Вас возник вопрос по поводу использования
сторонних библиотек. Это всё хорошие вопросы, но чтобы ответить на них,
нам нужно глубже изучить Zig, а пока нам придётся смириться с тем, что мы уже
знаем:
нам нужно глубже изучить Zig, а пока нам придётся обойтись тем, что мы уже
знаем, а именно:
* как импортировать стандартную библиотеку (`const std = @import("std");`)
* как импортировать свои собственные файлы (`const user = @import(models/user.zig)`)
@@ -154,23 +154,98 @@ fn add(a: i64, b: i64) i64 {
}
```
Программисты, пишущие на языках C или C++ наверняка заметят, что Zig
Программисты, пишущие на языках C или C++, наверняка заметят, что Zig
не требует объявления/определения функции до её использования, функция
`add` вызывается раньше (по тексту), чем встречается её определение.
Далее отметит тип `i64`. Вот некоторые другие целочисленные/вещественные типы:
Далее отметим тип `i64`. Вот некоторые другие целочисленные/вещественные типы:
`u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `u47`, `i47`, `u64`, `i64`, `f32` and `f64`.
Наличие в списке `u47` и `i47` это вовсе не проверка того, что Вы ещё не спите -
Zig умеет работать с целыми числами произвольного размера (в битах). Возможно,
ВЫ не будете использовать такие типы (`u1`, `s9` и т.п.), однако, иногда
Вы не будете использовать такие типы (`u1`, `s9` и т.п.), однако, иногда
они удобны или даже необходимы. Тип, который Вы точно будете часто использовать,
это `usize` - это целочисленный тип размером с указатель (для данной платформы) и
это тип представляет длину/размер чего-либо.
Давайте
Давайте (без всякой на то причины) изменим реализацию функции `add` вот таким
образом:
```zig
fn add(a: i64, b: i64) i64 {
a += b;
return a;
}
```
Мы получим ошибку в строчке, где `a += b`, "нельзя присваивать значение константе".
Это важное наблюдение, к которому мы ещё вернёмся позже: параметры функций являются
константами.
В Zig, ради лучшей читабельности, нет перегрузки функций, то есть нельзя сделать
несколько функций с одинаковыми именами, но с разными типами параметров
или с разным их количеством. На данный момент это всё, что нам нужно знать про функции.
## Структуры
Далее в нащем примере идёт создание экземпляра структуры `User`,
определение которой располагается после функции `main` и которое гласит:
```zig
pub const User = struct {
power: u64,
name: []const u8,
};
```
Поскольку эта структура у нас используется только в том же файле, где и
определена, то слово `pub` тут необязательно. Оно было использовано для
того, чтобы ознакомиться с экспортом определений.
Поля структуры оканчиваются запятой (в отличие от С) и им можно присвоить
значение по умолчанию (также в отличие от С):
```zig
pub const User = struct {
power: u64 = 0,
name: []const u8,
};
```
Когда мы создаём экземпляр структуры, *все* её поля должны быть проинициализированы.
Например, если использовать наше первоначальное определение структуры `User`
(у которой поле `power` не имеет значения по умолчанию) и написать
```
const user = User{.name = "Пётр"};
```
то мы получим ошибку, в которой будет сообщено, что поле `power` отсутствует.
Если же использовать определение, в котором для поля `power` заданом значение по умолчанию,
то тогда такой код успешно откомпилируется.
Структуры могут иметь методы, они могут содержать определения (включая другие структуры),
а также могут быть вообще пустыми (и в таком случае они работают как пространства имён).
```zig
pub const User = struct {
power: u64 = 0,
name: []const u8,
pub const SUPER_POWER = 9000;
fn diagnose(user: User) void {
if (user.power >= SUPER_POWER) {
std.debug.print("Вот это силища, больше, чем {d}!!!", .{SUPER_POWER});
}
}
};
```
Методы это просто обычные функции, которые можно вызвать, используя точку:
```zig
// вызвать функцию diagnose для некоторого экземпляра User
user.diagnose();
// предыдущая строчка это "синтаксический сахар" для вот такой полной формы:
User.diagnose(user);
```