On branch main
modified: src/ch08.md
This commit is contained in:
35
src/ch08.md
35
src/ch08.md
@@ -357,9 +357,9 @@ ptr_info.Pointer.child.writeAll(self, data);
|
|||||||
|
|
||||||
## Использование маркированных объединений
|
## Использование маркированных объединений
|
||||||
|
|
||||||
...
|
В качестве более простой альтернативы описанным схемам для эмуляции
|
||||||
|
интерфейсов можно применять маркированные объединения, вот полноценный
|
||||||
Вот рабочий полноценный пример:
|
рабочий пример:
|
||||||
|
|
||||||
```zig
|
```zig
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
@@ -391,3 +391,32 @@ pub fn main() !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Напомним, что когда в `switch` используется переменная, представляющая
|
||||||
|
собой маркированное объединение, захваченные значения (в примере
|
||||||
|
`|file|`) всегда имеют правильный тип (для примера это `File`).
|
||||||
|
|
||||||
|
Минусом такого подхода является то, что нужно заранее знать все возможные
|
||||||
|
реализации, поэтому он не подходит, например, для создания интерфейсов,
|
||||||
|
реализации которых могли бы создавать третьи стороны. Каждая возможная
|
||||||
|
реализация должна быть включена в объединение.
|
||||||
|
|
||||||
|
Если интерфейс используется только внутри какого-то приложения,
|
||||||
|
это ограничение роли не играет. Вы можете построить, к примеру,
|
||||||
|
объединение `Cache`, которое будет включать в себя все нужные
|
||||||
|
реализации, например, `InMemory`, `Redis` и `Postgresql`. Если
|
||||||
|
появляются новые механизмы, Вы просто обновляете объединение.
|
||||||
|
|
||||||
|
Во многих случаях интерфейс будет вызывать функции с реализациями
|
||||||
|
непосредственно. Для таких случаев можно использовать специальный
|
||||||
|
синтаксис, `inline else`:
|
||||||
|
|
||||||
|
```zig
|
||||||
|
switch (self) {
|
||||||
|
.null => {}, // do nothing
|
||||||
|
inline else => |impl| return impl.writeAll(data),
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Такой оборот `else` автоматически разворачивается,
|
||||||
|
то есть для каждого варианта получается правильный тип `impl`.
|
||||||
|
|||||||
Reference in New Issue
Block a user