This commit is contained in:
Rorik Star Platinum 2025-11-27 23:37:40 +03:00
parent f2b07c9f30
commit 17f37947f3
8 changed files with 485 additions and 16 deletions

View file

@ -0,0 +1,67 @@
## 1. Суть трейта `Deref`
Трейт `std::ops::Deref` позволяет кастомизировать поведение оператора разыменования `*`.
Главная цель — сделать **Smart Pointers** (умные указатели) взаимозаменяемыми с обычными ссылками в клиентском коде.
**Механизм работы:**
Когда вы пишете `*y` для типа, реализующего `Deref`, Rust неявно преобразует это в:
rust
`*(y.deref())`
1. Вызывается метод `deref()`, который возвращает **ссылку** на внутреннее значение (`&Target`).
2. Затем происходит обычное разыменование `*` этой полученной ссылки.
> **Важно:** Метод `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 применяет приведение типов в следующих случаях:
1. **`&T``&U`**: Если реализован `Deref` (Immutable to Immutable).
2. **`&mut T``&mut U`**: Если реализован `DerefMut` (Mutable to Mutable).
3. **`&mut T``&U`**: Если реализован `Deref` (Mutable to Immutable).
> **Критическое ограничение:** Приведение **Immutable (`&T`) → Mutable (`&mut U`)** невозможно.
> Это нарушило бы правила заимствования (Borrowing Rules), так как нельзя гарантировать уникальность создаваемой изменяемой ссылки, если исходная ссылка была неизменяемой (а их может быть много).
4. [https://doc.rust-lang.org/book/ch15-02-deref.html](https://doc.rust-lang.org/book/ch15-02-deref.html)