rust解引用
在 Rust 中,解引用(Dereferencing)是访问指针或引用所指向内存位置数据的行为。它是 Rust 所有权和内存模型中的核心操作。
1. 基础语法:* 运算符
使用
* 运算符可以从引用或指针中提取出它指向的值。let x = 10;
let y = &x; // y 是 x 的引用 (&i32)
let z = *y; // 解引用:z 获得了值 10 (i32)
2. 解引用与所有权
解引用的行为取决于数据的类型:
- Copy 类型(如
i32,bool):解引用会创建一个副本,原数据不受影响。 - 非 Copy 类型(如
String,Vec):- 你不能通过解引用移走所有权。例如
let s2 = *s_ref;会报错,除非该类型实现了Copy。 - 通常只能通过解引用来修改数据(如果拥有
&mut权限)。
- 你不能通过解引用移走所有权。例如
3. 隐式解引用强制转换 (Deref Coercion)
这是 Rust 为了提升开发体验而设计的“魔法”。当你在某个类型上调用方法,或者将其传递给函数参数,且该类型实现了
Deref trait 时,Rust 会自动尝试进行解引用。可参考资料1.典型例子:
String 到 &strfn hello(name: &str) { println!("Hello, {}!", name); }
let s = String::from("Rust");
hello(&s); // 自动解引用:&String 变为 &str
编译器会自动执行
&s -> &(*s) -> &str 的转换。4. 显式解引用:* 与 . 的区别
在访问结构体字段时,Rust 会自动解引用,你不需要手动写
*:struct Point { x: i32, y: i32 }
let p = Point { x: 1, y: 2 };
let r = &p;
// 自动解引用,不需要写 (*r).x
println!("{}", r.x);
5. Deref 与 DerefMut 特征
你可以为自定义类型实现这两个特征,使你的类型表现得像指针(如
Box<T>, Rc<T>, Arc<T>)。Deref: 允许通过*进行只读访问。DerefMut: 允许通过*进行可变修改(需配合&mut)。
use std::ops::Deref;
struct MyBox<T>(T);
impl<T> Deref for MyBox<T> {
type Target = T;
fn deref(&self) -> &Self::Target { &self.0 }
}
6. 解引用使用技巧
- 匹配人体工学(Match Ergonomics):在
match或if let中,当你对一个引用进行匹配时,内部变量会自动获得引用权限,你通常不需要显式解引用或写ref。 - 智能指针:在高性能场景中,通过
Deref机制,你可以将复杂的包装类型(如受锁保护的资源)当作内部原始数据来操作。 - 原始指针解引用:对于
*const T或*mut T,解引用必须放在unsafe块中。
总结
*: 显式解引用,用于获取值或修改&mut指向的内容。.: 自动解引用,用于访问属性和方法。- Deref Coercion: 编译器的自动服务,让不同包装层级的引用能够无缝协作。
参考资料:
浙公网安备 33010602011771号