hardware
This commit is contained in:
parent
f2b07c9f30
commit
17f37947f3
8 changed files with 485 additions and 16 deletions
67
20-dev/00-rust/smart pointers/deref.md
Normal file
67
20-dev/00-rust/smart pointers/deref.md
Normal 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)
|
||||
Loading…
Add table
Add a link
Reference in a new issue