结论:实现 Deref(Target 关联类型 + deref(&self) -> &Target)的类型,在需要 &Target 的地方可以自动把 &Self 强制转换(deref coercion)过去。这是 String 能当 &str 用、Box<T>/Rc<T> 能透明调用 T 方法的原因。
展开:触发场景有两个:1)函数参数类型不匹配时,编译器反复调用 deref 直到类型吻合,如 &String → &str;2)方法调用时自动插入任意数量的 * 或 deref() 来找匹配方法。约束:解引用转换只发生在已有引用的前提下(&x、&mut x),DerefMut 对应可变场景。易错点:1)不要在自定义类型上滥用 Deref 模拟继承——它拿不到 trait 多态,还会让 API 混乱,官方指南建议只用于智能指针;2)方法解析顺序是"固有方法 → Deref 链",可能遮蔽你期望的方法。
use std::ops::Deref;
struct Wrapper(String);
impl Deref for Wrapper {
type Target = str;
fn deref(&self) -> &str { &self.0 }
}
fn shout(s: &str) { println!("{}", s.to_uppercase()); }
let w = Wrapper("hi".into());
shout(&w); // &Wrapper 自动转为 &str
追问方向:AsRef 与 Deref 的分工、为什么 Deref 能让智能指针"透明"。