© Anton Dolganin 2026
В Rust создание обертки над типом (struct Username(String)) полезно для строгой типизации, но неудобно в использовании — приходится постоянно обращаться к полю .0. Использование трейта Deref позволяет обертке «притворяться» внутренним типом.
Зачем это нужно
Username и Email, хотя оба — строки. Это дает не сам Deref, а само создание обертки..len(), .is_empty(), .contains()) без дублирования кода.Реализация
use std::ops::Deref;
struct Username(String); // Newtype
impl Deref for Username {
type Target = str; // Указываем целевой тип для разыменования
fn deref(&self) -> &Self::Target {
&self.0 // Возвращаем ссылку на внутренние данные
}
}
Как это работает на практике
Благодаря Deref-coercion, компилятор автоматически вызывает .deref(), когда видит, что тип не совпадает с ожидаемым, но может быть к нему приведен.
let name = Username("Anton".to_string());
// 1. Прямой вызов методов внутреннего типа &str
println!("{}", name.len());
println!("{}", name.contains("a"));
// 2. Использование в функциях, принимающих &str
fn greet(s: &str) {
println!("Hello, {s}");
}
greet(&name); // Работает автоматически
Не злоупотребляйте. Этот паттерн стоит использовать только тогда, когда ваша обертка логически является «умным указателем» или расширением внутреннего типа. Если методы внутреннего типа могут нарушить инварианты вашей структуры, лучше делегировать методы вручную.
© Anton Dolganin 2026