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

Типы-токены

Типы с приватными конструкторами можно использовать как доказательство выполнения инвариантов.

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

pub mod token {
    // Публичный тип с приватными полями за границей модуля.
    pub struct Token { proof: () }

    pub fn get_token() -> Option<Token> {
        Some(Token { proof: () })
    }
}

pub fn protected_work(token: token::Token) {
    println!("We have a token, so we can make assumptions.")
}

fn main() {
    if let Some(token) = token::get_token() {
        // У нас есть токен, поэтому мы можем выполнить эту работу.
        protected_work(token);
    } else {
        // Мы не смогли получить токен, поэтому не можем вызвать `protected_work`.
    }
}
This slide and its sub-slides should take about 95 minutes.
  • Мотивация: мы хотим ограничить доступ пользователя к функциональности, пока он не выполнит определённое действие.

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

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

  • Спросите: зачем здесь нужно поле proof: ()?

    Без proof: () у Token не было бы приватных полей, и пользователи могли бы создавать значения Token как угодно.

    Продемонстрируйте: попробуйте создать токен вручную в main и покажите ошибку компиляции. Продемонстрируйте: удалите поле proof из Token, чтобы показать, как пользователи могли бы создать Token, если бы у него не было приватных полей.

  • Поскольку тип Token находится за границей модуля (token), пользователи вне этого модуля не могут создать значение самостоятельно: у них нет доступа к полю proof.

    Разработчик API определяет методы и функции, которые создают эти токены. Пользователь — нет.

    Токен становится доказательством того, что пользователь выполнил условия доступа, установленные разработчиком API.

  • Спросите: как разработчик API может случайно создать способы обойти это ограничение?

    Ожидаемые ответы: «реализации сериализации», другие парсеры и реализации «из строки», а также реализация Default.