rust解引用

在 Rust 中,解引用(Dereferencing)是访问指针或引用所指向内存位置数据的行为。它是 Rust 所有权和内存模型中的核心操作。

1. 基础语法:* 运算符

使用 * 运算符可以从引用或指针中提取出它指向的值。
let x = 10;
let y = &x;     // y 是 x 的引用 (&i32)
let z = *y;     // 解引用:z 获得了值 10 (i32)

2. 解引用与所有权

解引用的行为取决于数据的类型:
  • Copy 类型(如 i32bool):解引用会创建一个副本,原数据不受影响。
  • 非 Copy 类型(如 StringVec):
    • 你不能通过解引用移走所有权。例如 let s2 = *s_ref; 会报错,除非该类型实现了 Copy
    • 通常只能通过解引用来修改数据(如果拥有 &mut 权限)。

3. 隐式解引用强制转换 (Deref Coercion)

这是 Rust 为了提升开发体验而设计的“魔法”。当你在某个类型上调用方法,或者将其传递给函数参数,且该类型实现了 Deref trait 时,Rust 会自动尝试进行解引用。可参考资料1.
典型例子:String 到 &str
fn 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: 编译器的自动服务,让不同包装层级的引用能够无缝协作。
参考资料:

1.rust语言String解引用Deref细探

2.rust智能指针Box

3.rust关键字unsafe

4.rust语言二级指针

5.rust和内部可变性模式RefCell<T>

6.指针和引用的区别(c/c++)

 

posted @ 2025-12-30 17:21  PKICA  阅读(3)  评论(0)    收藏  举报