3.8 KiB
1. Суть трейта Deref
Трейт std::ops::Deref позволяет кастомизировать поведение оператора разыменования *.
Главная цель — сделать Smart Pointers (умные указатели) взаимозаменяемыми с обычными ссылками в клиентском коде.
Механизм работы:
Когда вы пишете *y для типа, реализующего Deref, Rust неявно преобразует это в:
rust
*(y.deref())
-
Вызывается метод
deref(), который возвращает ссылку на внутреннее значение (&Target). -
Затем происходит обычное разыменование
*этой полученной ссылки.
Важно: Метод
derefвозвращает именно ссылку, а не значение, чтобы не перемещать (move) владение данными из умного указателя.
2. Реализация
Для реализации собственного умного указателя (как в примере MyBox<T>) нужно:
-
Указать ассоциированный тип
Target(тип данных внутри обертки). -
Реализовать метод
deref.
rust
use std::ops::Deref; impl<T> Deref for MyBox<T> { type Target = T; fn deref(&self) -> &Self::Target { &self.0 // Возвращаем ссылку на поле кортежной структуры } }
3. Deref Coercion (Неявное приведение)
Это механизм эргономики Rust, который автоматически преобразует ссылки при передаче аргументов в функции или методы.
-
Как работает: Если тип
TреализуетDeref<Target=U>, то&Tможет быть неявно приведен к&U. -
Цепочки: Coercion работает рекурсивно.
-
Пример:
&MyBox<String>→deref→&String→deref→&str. -
Это позволяет передавать
&MyBox<String>в функцию, ожидающую&str.
-
-
Цена: Работает на этапе компиляции (compile-time resolution), runtime оверхеда нет.
Без этого механизма код превратился бы в нагромождение символов: &(*m)[..] вместо простого &m.
4. Взаимодействие с изменяемостью (Mutability)
Для изменяемых ссылок существует зеркальный трейт DerefMut.
Три правила приведения (Coercion rules):
Rust применяет приведение типов в следующих случаях:
-
&T→&U: Если реализованDeref(Immutable to Immutable). -
&mut T→&mut U: Если реализованDerefMut(Mutable to Mutable). -
&mut T→&U: Если реализованDeref(Mutable to Immutable).
Критическое ограничение: Приведение Immutable (
&T) → Mutable (&mut U) невозможно.
Это нарушило бы правила заимствования (Borrowing Rules), так как нельзя гарантировать уникальность создаваемой изменяемой ссылки, если исходная ссылка была неизменяемой (а их может быть много).