On branch main

modified:   src/ch02.md
modified:   src/ch03.md
new file:   src/ex-ch03-01.zig
new file:   src/ex-ch03-02.zig
This commit is contained in:
zed
2023-11-14 16:55:20 +03:00
parent 66862b3fb7
commit a38dc8a68d
4 changed files with 161 additions and 5 deletions

View File

@@ -642,8 +642,8 @@ try action(req, res);
Довольно часто используется комбинация объединения с ошибкой с опциональным типом.
Если набор ошибок выводится, то это записывается вот так:
```
/ load the last saved game
```zig
// load the last saved game
pub fn loadLast() !?Save {
// TODO
return null;
@@ -655,7 +655,7 @@ pub fn loadLast() !?Save {
извлечь ошибку и затем `orelse`, чтобы развернуть необязательное значение,
вот рабочий скелет:
```
```zig
const std = @import("std");
pub fn main() void {
@@ -686,5 +686,3 @@ pub const Save = struct {
ещё более широкие возможности, то, что мы видели в первых двух главах,
уже составляет значительную часть языка. И это будет служить нам базой
при исследовании более сложных тем без отвлечения на синтаксис.

View File

@@ -0,0 +1,130 @@
# Руководство по стилю оформления.
В это короткой главе мы рассмотрим 2 правила оформления,
которые обеспечивабтся компилятором, а также различные
соглашения об именовании в стандартной библиотеке Zig.
## Неиспользуемые переменные
Zig не позволяет оставлять переменные неиспользованными.
При компиляции следующего кода мы получим 2 ошибки:
```zig
const std = @import("std");
pub fn main() void {
const sum = add(8999, 2);
}
fn add(a: i64, b: i64) i64 {
// обратите внимание, что тут a + a, а не a + b
return a + a;
}
```
```
src/ex-ch03-01.zig:5:11: error: unused local constant
const sum = add(8999, 2);
^~~
src/ex-ch03-01.zig:8:16: error: unused function parameter
fn add(a: i64, b: i64) i64 {
```
Первая ошибка возникла потому, что локальная константа `sum` никак
после присваивания ей значения не используется. Вторая ошибка связана
с тем обстоятельством, что `b` (второй аргумент функции `add`)
тоже внутри функции никак не используется. Однако, у Вас могут
быть вполне уважительные причины реально иметь в своём
коде неиспользованные локальные переменные или параметры функций,
поэтому в Zig возможноть игнорировать ненужные значения
путём присваивания их символу `_`, вот таким образом:
```zig
const std = @import("std");
pub fn main() void {
_ = add(8999, 2);
// или
sum = add(8999, 2);
_ = sum;
}
fn add(a: i64, b: i64) i64 {
_ = b;
return a + a;
}
```
Вместо того, чтобы внутри тела `add` написать `_ = b;`, мы могли
бы использовать `_` в её заголовке, то есть `fn add(a: i64, _: i64) i64 {`,
однако, такой вариант менее желателен, посольку заставляет пользователя
гадать, что собой представляет параметр `b`.
Обратите также внимание, что `std` в этом примере никак не используется,
однако, это не порождает ошибку. Возможно, в будущем Zig будет считать
это ошибкой.
## Маскирование/затенение имён (shadowing)
Zig не ползволяет одному идентификатору "перекрывать" собой другой,
используя то же самое имя. Следующий код для чтения из сокета не является
корректным:
```zig
fn read(stream: std.net.Stream) ![]const u8 {
var buf: [512]u8 = undefined;
const read = try stream.read(&buf);
if (read == 0) {
return error.Closed;
}
return buf[0..read];
}
```
Тут переменная `read` конфликтует с именем самой функции.
## Соглашения об именовании
За исключением правил, диктуемых компилятором, Вы, разумеется,
вольны использовать такие такие соглашения об именах, какие Вам больше
нравятся. Однако, соверешенно не вредно понимать собственные
соглашения Zig, поскольку стандартная библиотека, которой Вы,
безуловно, будете пользоваться, придерживается этих соглашений.
Отступы в Zig - это 4 пробела. Как правило, текстовые редакторы
можно настроить так, чтобы клавиша `Tab` вставляла именно 4 пробела,
а не символ табуляции и это гораздо удобней, 4 раза нажимать пробел.
Имена функций пишутся в `camelCase`, имена переменных - в `snake_case`.
Типы пишутся в `PascalCase`. Есть одно интересное перечение этих 3-х правил.
Переменные, которые хранят тип или функции, которые возвращают тип,
так же, как и сами типы, пишутся в `PascalCase`. Мы уже видели нечто подобное:
```zig
// смотрим на встроенную функцию '@TypeOf'
std.debug.print("{any}\n", .{@TypeOf(.{.year = 2023, .month = 8})});
```
Мы уже видели некторые другие встроенные функции, как то `@import`, `@rem` и `@intCast`.
Поскольку это функции, их имена записаны в `camelCase`. Однако, `@TyoeOf` это тоже
(встроенная) функция, но она почему то написана в `PascalCase`. А это потому,
что она возвращает *тип* и поэтому для её имени используется соглашение для типов,
а не для функций. Если бы присваивали результат функции `@TypeOf` какой-то переменной,
эту переменную так же следовало бы писать в `CamelCase`:
```zig
const T = @TypeOf(3)
std.debug.print("{any}\n", .{T});
```
У компилятор Zig есть команда `fmt`, которая форматирует обозначенные файлы
по своим правилам. Впрочем, такое форматирование затрагивает не всё -
например, оно подправит отступы и положение фигурных скобок для блоков,
но регистр идентификаторов останется как есть.

11
src/ex-ch03-01.zig Normal file
View File

@@ -0,0 +1,11 @@
const std = @import("std");
pub fn main() void {
const sum = add(8999, 2);
}
fn add(a: i64, b: i64) i64 {
// обратите внимание, что тут a + a, а не a + b
return a + a;
}

17
src/ex-ch03-02.zig Normal file
View File

@@ -0,0 +1,17 @@
const std = @import("std");
pub fn main() void {
_ = add(8999, 2);
// или
// sum = add(8999, 2);
// _ = sum;
// нет, так тоже 'error: use of undeclared identifier 'sum''
}
fn add(a: i64, b: i64) i64 {
_ = b;
return a + a;
}