Расширение чужих типов
Трейт-расширение — это локальное определение трейта, основная цель которого — добавить новые методы внешним типам.
// Copyright 2025 Google LLC
// SPDX-License-Identifier: Apache-2.0
mod ext {
pub trait StrExt {
fn is_palindrome(&self) -> bool;
}
impl StrExt for str {
fn is_palindrome(&self) -> bool {
self.chars().eq(self.chars().rev())
}
}
}
fn main() {
// Подключите трейт-расширение в область видимости...
pub use ext::StrExt as _;
// ...а затем вызывайте его методы так, как если бы это были собственные методы
assert!("dad".is_palindrome());
assert!(!"grandma".is_palindrome());
}
-
По соглашению к имени трейта-расширения добавляют суффикс
Ext.Этот суффикс показывает, что трейт в первую очередь предназначен для расширения, поэтому его не предполагается реализовывать за пределами крейта, в котором он определён.
Авторитетным источником по соглашениям об именовании считается RFC «Extension Trait».
-
Реализация трейта-расширения для внешнего типа должна находиться в том же крейте, что и сам трейт, иначе вас остановит правило сироты в Rust.
-
Трейт-расширение должен быть в области видимости при вызове его методов.
Закомментируйте оператор
useв примере, чтобы показать ошибку компилятора, которая возникает, если попытаться вызвать метод-расширение без подключённого соответствующего трейта-расширения. -
В примере выше используется импорт с подчёркиванием (
use ext::StringExt as _), чтобы свести к минимуму вероятность конфликта имён с другими импортированными трейтами.При импорте с подчёркиванием трейт считается находящимся в области видимости, и его методы можно вызывать для типов, которые реализуют этот трейт. Однако его символ напрямую недоступен. Например, это не позволяет использовать этот трейт в предложении
where.Поскольку трейты-расширения не предназначены для использования в предложениях
where, их по соглашению импортируют с помощью импорта с подчёркиванием.