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

Sealed-трейты: пользователи не могут их расширять

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

// крейт может обращаться к модулю «sealed» и его трейту, а проекты,
// которые от него зависят, — нет.
mod sealed {
    pub trait Sealed {}
    impl Sealed for String {}
    impl Sealed for Vec<u8> {}
    //...
}

pub trait APITrait: sealed::Sealed {
    /* методы */
}
impl APITrait for String {}
impl APITrait for Vec<u8> {}
  • Мотивация: мы хотим, чтобы в крейте был код, управляемый трейтами, но не хотим, чтобы проекты, зависящие от этого крейта, могли реализовывать трейт.

Почему?

На данный момент трейт можно считать нестабильным для реализаций в зависимых проектах.

Или иначе: предметная область несёт высокий риск наивных реализаций трейта (например, в криптографии).

  • Механизм, которым мы этого добиваемся, — ограничение доступа к супертрейту, из-за чего зависимые пользователи не могут реализовывать этот трейт для своих типов.

  • Почему бы не использовать перечисления?

    • Перечисления раскрывают детали реализации — «это работает для этих типов».

    • Пользователям нужно использовать конструкторы вариантов перечисления, чтобы работать с API.

    • Пользователи могут использовать перечисление как тип в своём коде, и при изменении перечисления им нужно обновлять свой код под эти изменения.

    • Перечисления требуют ветвления по вариантам, тогда как sealed-трейты позволяют компилятору генерировать мономорфизированные функции для каждого типа.