Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Паттерн typestate с обобщениями

Комбинируя моделирование typestate с обобщениями, мы можем выразить более широкий набор допустимых состояний и переходов, не дублируя логику. Этот подход особенно полезен, когда количество состояний растёт или когда несколько состояний имеют общее поведение, но различаются по структуре.

// Copyright 2025 Google LLC
// SPDX-License-Identifier: Apache-2.0

struct Serializer<S> {
    // [...]
    indent: usize,
    buffer: String,
    state: S,
}

struct Root;
struct Struct<S>(S);
struct Property<S>(S);
struct List<S>(S);

Теперь у нас есть все инструменты, необходимые для реализации методов Serializer и определений его типов состояний. Это гарантирует, что наш API допускает только корректные переходы, как показано на следующей схеме:

  • Используя обобщения для отслеживания родительского контекста, мы можем построить сериализаторы с произвольной вложенностью, которые обеспечивают корректные переходы между состояниями структуры, списка и свойства.

  • Это позволяет построить рекурсивную структуру, сохраняя строгий контроль над тем, какие методы доступны в каждом состоянии.

  • Методы, общие для всех состояний, можно определить для любого S в Serializer<S>.

  • Маркерные типы (например, List<S>) не создают накладных расходов ни по памяти, ни во время выполнения, так как не содержат данных, кроме возможного типа нулевого размера (Zero-Sized Type). Их единственная роль — обеспечивать корректное использование API с помощью системы типов.