1 Commits
v1,1 ... v1.2

Author SHA1 Message Date
zed
2e54141256 On branch main, https://github.com/dee0xeed/learning-zig-rus/issues/1
Changes to be committed:
modified:   src/ch08.md
2025-05-28 18:41:12 +03:00

View File

@@ -217,11 +217,10 @@ const Writer = struct {
const gen = struct {
pub fn writeAll(pointer: *anyopaque, data: []const u8) anyerror!void {
const self: T = @ptrCast(@alignCast(pointer));
return ptr_info.Pointer.child.writeAll(self, data);
return ptr_info.pointer.child.writeAll(self, data);
}
};
return .{
.ptr = ptr,
.writeAllFn = gen.writeAll,
@@ -289,18 +288,18 @@ union), которая полностью описывает тип. Далее
возможности Zig по генерации исходного кода во время компиляции.
Последняя часть этого кода это вызов функции посредством
`ptr_info.Pointer.child.writeAll(self, data)`. Встроенная функция
`ptr_info.pointer.child.writeAll(self, data)`. Встроенная функция
`@@typeInfo(T)` возвращает `std.builtin.Type`, а это, как уже было
отмечено, маркированная объединение, которое описывает тот или иной тип.
Оно может описывать 24 разновидности типов, как то целые числа,
необязательные значения, структуры, указатели и т.д. Каждый тип имеет
необязательные значения, структуры, указатели и т.д. Каждый тип имеет
свои особенные свойства. Так, целые числа обладают "знаковостью"
(`signedness`), в то время как другие типы такого свойства не имеют. Вот
так выглядит `@typeInfo(*File)`:
```zig
builtin.Type{
.Pointer = builtin.Type.Pointer{
.pointer = builtin.Type.Pointer{
.address_space = builtin.AddressSpace.generic,
.alignment = 4,
.child = demo.File,
@@ -308,14 +307,14 @@ builtin.Type{
.is_const = false,
.is_volatile = false,
.sentinel = null,
.size = builtin.Type.Pointer.Size.One
.size = builtin.Type.Pointer.Size.one
}
}
```
Поле `child` это фактический тип сущности, на которую показывает
указатель. Когда мы вызываем `init`, передавая ей `*File`,
`ptr_info.Pointer.child.writeAll(...)` транслируется в
`ptr_info.pointer.child.writeAll(...)` транслируется в
`File.writeAll(...)`, то есть получается именно то, что мы и хотели.
Если вы посмотрите на другие применения такой витиеватой схемы,
@@ -323,8 +322,8 @@ builtin.Type{
получения информации о типе:
```zig
if (ptr_info != .Pointer) @compileError("ptr must be a pointer");
if (ptr_info.Pointer.size != .One) @compileError("ptr must be a single item pointer");
if (ptr_info != .pointer) @compileError("ptr must be a pointer");
if (ptr_info.pointer.size != .one) @compileError("ptr must be a single item pointer");
```
Таким образом делаются дополнительные проверки во время компиляции,
@@ -334,13 +333,13 @@ if (ptr_info.Pointer.size != .One) @compileError("ptr must be a single item poin
Также вместо вызова функции посредством
```zig
ptr_info.Pointer.child.writeAll(self, data);
ptr_info.pointer.child.writeAll(self, data);
```
можно встретить такое
```zig
@call(.always_inline, ptr_info.Pointer.child.writeAll, .{self, data});
@call(.always_inline, ptr_info.pointer.child.writeAll, .{self, data});
```
Вызов функции напрямую (как мы это и делали) по сути ничем не отличается
@@ -358,7 +357,7 @@ ptr_info.Pointer.child.writeAll(self, data);
## Использование маркированных объединений
В качестве более простой альтернативы описанным схемам для эмуляции
В качестве более простой альтернативы описанным схемам для эмуляции
интерфейсов можно применять маркированные объединения, вот полноценный
рабочий пример: