On branch main

modified:   src/ch01.md
This commit is contained in:
zed
2023-11-09 23:56:45 +03:00
parent 35b4827a2a
commit 42167bf7ce

View File

@@ -218,7 +218,7 @@ pub const User = struct {
const user = User{.name = "Пётр"};
```
то мы получим ошибку, в которой будет сообщено, что поле `power` отсутствует.
Если же использовать определение, в котором для поля `power` заданом значение по умолчанию,
Если же использовать определение, в котором для поля `power` задано значение по умолчанию,
то тогда такой код успешно откомпилируется.
Структуры могут иметь методы, они могут содержать определения (включая другие структуры),
@@ -249,3 +249,86 @@ user.diagnose();
User.diagnose(user);
```
Что касается инструкции `if` внутри функции `diagnose`, то она вполне
самоочевидна. Мы исследуем это подробнее в следующей части.
Итак, функция `diagnose` определена внутри типа `User` и принимает
такую же структуру в качестве своего первого и единственного параметра.
Соответственно, мы можем вызывать эту функцию, используя точку,
в "сахарном" варианте. Однако, функции внутри структуры вовсе не обязаны
следовать такому правилу. Один из распространённых примеров - это
функция инициализации:
```zig
pub const User = struct {
power: u64 = 0,
name: []const u8,
pub fn init(name: []const u8, power: u64) User {
return User{
.name = name,
.power = power,
};
}
}
```
Использование именно такого имени (`init`) является просто соглашением,
то есть в каких-то случаях более уместными могут показаться и другие имена,
например, `open`. Если Вы не программист на C/C++, то такой синтаксис
инициализации полей (с точкой, `.name = name`) может показаться Вам
слегка странным, но со временем Вы к этому привыкнете.
Когда мы создавали пользователя `Пётр`, мы объявили экземпляр
`user` как константу (`const`):
```zig
const user = User{
.power = 9001,
.name = "Пётр",
};
```
Это означает, что мы не можем модифицировать эту "переменную".
Чтобы иметь возможность модификации, нужно объявить экземпляр
при помощи ключевого слова `var`, а не `const`. Возможно,
Вы так же заметили, что тип переменной `user` выводится из того,
что в неё присваивается. Мы могли бы написать всё явно, то есть вот так:
```zig
const user: User = User{
.power = 9001,
.name = "Пётр",
};
```
Мы ещё увидим в дальнеёшем случаи, когда явное указание типа переменной
обязательно, но в большинстве случаев код более читабелен без
явного указания типа. Вывод типов работает также и в другую сторону:
```zig
const user: User = .{
.power = 9001,
.name = "Пётр",
};
```
Впрочем, такое использование не особо употребительно. Одно из мест,
где это используется - возвращение структуры из функции, тут тип
может быть выведен из типа возвращаемого значения функции.
Более вероятно, что наша функция инициализации выглядела бы так:
```zig
pub fn init(name: []const u8, power: u64) User {
// вместо того, чтобы возвращать User{...}
return .{
.name = name,
.power = power,
};
}
```
Как и большинство вещей, которые мы уже немного изучили,
мы рассмотрим структуры более подробно в дальнейшем.
## Массивы и срезы