rust语言学习笔记Trait(十一)Deref、DerefMut(解引用)

DerefDerefMut 是用于实现‌智能指针 ‌行为的核心 Trait。它们允许自定义类型像普通引用一样工作,支持解引用操作符 *

1、什么是 Deref

std::ops::Deref Trait 允许你重载解引用操作符 *

  • 普通引用 ‌:&T 指向内存中的值,使用 * 可以获取该值。
  • 智能指针 ‌:如 Box<T>, Rc<T>, Arc<T>,它们是结构体,但实现了 Deref,因此可以像 &T 一样被解引用。

(1)Deref 的定义

rust 复制代码
pub trait Deref {
    // 关联类型:解引用后得到的目标类型
    type Target: ?Sized;

    // 核心方法:返回对内部数据的不可变引用
    fn deref(&self) -> &Self::Target;
}

(2)DerefMut (可变解引用)的定义

rust 复制代码
pub trait DerefMut: Deref {
    fn deref_mut(&mut self) -> &mut Self::Target;
}

2、自定义结构体实现 DerefDerefMut

  • 实现 DerefMut,必须首先实现 Deref
rust 复制代码
use std::ops::{Deref, DerefMut};

// 自定义结构体
#[derive(Debug)]
struct MyBox<T>(T);

// 实现 deref 不可变引用
impl<T> Deref for MyBox<T> {
    type Target = T;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

// 实现 deref_mut 可变引用,必须先实现 deref
impl<T> DerefMut for MyBox<T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

fn main() {
    let mut ms = MyBox(8);
    
    *ms += 5;                       // 自动调用可变引用
    println!("{:?}", *ms);          // 自动调用不可变引用
    
    *(ms.deref_mut()) -= 3;          // 手动调用可变引用
    println!("{:?}", *(ms.deref())); // 手动调用不可变引用
}
  • *ms += 5,编译器查找 DerefMut 实现。

    可变引用转换过程:*ms -> *(ms.deref_mut()) -> *(&mut T) -> mut T
  • println!("{:?}", *ms);,编译器查找 Deref 实现。

    不可变引用转换过程:*ms -> *(ms.deref()) -> *(&T) -> T

3、最佳实践与陷阱

✅ 应该做的

  1. 仅为智能指针实现 Deref
    Rust 官方建议 Deref 应仅用于智能指针类型(如 Box, Rc, Arc, RefCell 的守卫等)。目的是让智能指针"透明",让用户感觉像是在操作内部数据。
  2. 利用 Deref 提供切片视图 ‌:
    例如 Vec<T> 实现 Deref<Target = [T]>String 实现 Deref<Target = str>。这使得你可以直接在这些集合上使用切片的方法。

❌ 不应该做的

  1. 不要为了便利而滥用 Deref
    例如,不要为一个 User 结构体实现 Deref<Target = String> 以便直接调用字符串方法。这会隐藏数据的真实结构,导致代码难以阅读和维护。如果需要转换,请实现 AsRef<str> 或提供显式方法。
  2. Deref 不应失败
    deref() 方法签名返回的是引用 &Target,而不是 ResultOption。这意味着解引用操作必须总是成功。如果解引用可能失败(例如网络请求未完成),不应使用 Deref
  3. 避免循环 Deref
    确保 Target 类型不会间接地又解引用回原类型,否则会导致编译器无限递归或栈溢出。
相关推荐
vivo互联网技术24 分钟前
从 Web 到桌面:基于 Tauri 2.0 + Vue 3 打造 vivo 线下门店「大头贴」拍照体验系统
前端·rust
Rust研习社4 小时前
这 8 个 Rust 学习资源值得每个新手收藏起来
后端·rust·编程语言
通信小呆呆1 天前
当算法有了“五感”:多模态数据融合如何向人体感官协同学习?
人工智能·学习·算法·机器学习·机器人
H__Rick1 天前
自动对焦学习-3
人工智能·学习·计算机视觉
Daisy Lee1 天前
量化学习-第1章-什么是量化金融
学习·金融·datawhale
Alsn861 天前
等待学习-学习目录:Docker 容器安全攻防
学习·安全·docker
星栈1 天前
10 分钟跑起第一个 Dioxus 应用:`dx` CLI、`rsx!` 和热更新好不好用
前端·rust·前端框架
YM52e1 天前
买菜计算器小应用 - HarmonyOS ArkUI 开发实战-PC版本
学习·华为·harmonyos·鸿蒙·鸿蒙系统
小雨下雨的雨1 天前
HarmonyOS ArkUI训练营入门-组件掌握系列-Animation 动画效果实现-PC版本
学习·华为·harmonyos·鸿蒙
闪闪发亮的小星星1 天前
高斯光以及高斯光公式解释
笔记