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-трейты позволяют компилятору генерировать мономорфизированные функции для каждого типа.
-