On branch main
modified: src/ch01.md
This commit is contained in:
93
src/ch01.md
93
src/ch01.md
@@ -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);
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user