Rust~Pin的new

Pin::new(&mut my_struct) 中传了一个 MyStruct 实例的引用,但是 Pin::new 需要的参数又是 Ptr,这种转换是怎么做到的

注意,区别于其他语言,Ptr 是一个范型,<Ptr: Deref<Target: Unpin>>

rust 复制代码
impl<Ptr: Deref<Target: Unpin>> Pin<Ptr> {
    pub const fn new(pointer: Ptr) -> Pin<Ptr> {
        // SAFETY: the value pointed to is `Unpin`, and so has no requirements
        // around pinning.
        unsafe { Pin::new_unchecked(pointer) }
    }
    ... ...

DerefMut 特征:意味着 P 是一个可以解引用为可变引用的类型

Target 需要实现 Unpin 特征,表示解引用后的目标类型可以安全地被移动

&mut T 类型实现了 DerefMut 特征,它可以解引用为 T 类型。因此,&mut MyStruct 满足 Pin::new 方法中泛型参数 P 的

DerefMut 约束。

Rust 有一个自动解引用机制,当在一个需要特定类型的上下文中使用一个实现了 Deref 或 DerefMut 特征的值时,编译器会自动进行解引用操作,直到得到所需的类型。在 Pin::new(&mut my_struct) 这个调用中,&mut MyStruct 实现了 DerefMut 特征,编译器会根据 Pin::new 方法的要求进行必要的解引用,最终匹配到合适的类型。

示例

rust 复制代码
use std::pin::Pin;

struct MyStruct {
    value: i32,
}

fn main() {
    let mut my_struct = MyStruct { value: 42 };
    // 使用我们定义的 new 函数创建一个 Pin 实例
    let pinned_struct: Pin<&mut MyStruct> = Pin::new(&mut my_struct);

    // 由于 MyStruct 实现了 Unpin 特征,我们可以安全地获取内部可变引用
    let inner_mut = Pin::into_inner(pinned_struct);
    inner_mut.value = 100;

    println!("The updated value is: {}", my_struct.value);
}

&mut T 类型实现了 DerefMut 特征,它可以解引用为 T 类型

引用是一种轻量级的数据类型,它指向另一个值在内存中的位置。&mut T 表示一个可变引用,它允许在不获取值的所有权的情况下,对其所指向的值进行修改。引用的主要目的是提供一种安全、高效的方式来访问和操作内存中的数据。

DerefMut 特征定义在 Rust 标准库中,其核心目的是为类型提供可变解引用的能力

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

DerefMut 特征继承自 Deref 特征,这意味着实现 DerefMut 的类型也必须实现 Deref。

deref_mut 方法接收一个可变引用 &mut self,并返回一个指向 Self::Target 类型的可变引用。通过实现这个方法,类型可以自定义其可变解引用的行为。

&mut T 实现 DerefMut 特征是为了让可变引用在使用时更加灵活和统一。当使用 &mut T 类型的值时,有时需要直接访问其所指向的 T 类型的值,通过实现 DerefMut 特征,我们可以方便地进行解引用操作。

代码一致性:实现 DerefMut 特征使得 &mut T 类型在使用上与其他实现了 DerefMut 的类型保持一致。例如,可以使用相同的语法来解引用 &mut T 和自定义的智能指针类型。

自动解引用:Rust 的自动解引用机制会根据上下文自动调用 deref_mut 方法,从而简化代码。例如,当在一个需要 T 类型的上下文中使用 &mut T 类型的值时,编译器会自动进行解引用操作。

示例

rust 复制代码
fn main() {
    let mut num = 42;
    let mut ref_num = &mut num;

    // 手动解引用
    let deref_num = *ref_num;
    println!("Dereferenced number: {}", deref_num);

    // 自动解引用
    let result = add_one(ref_num);
    println!("Result after adding one: {}", result);
}

fn add_one(x: i32) -> i32 {
    x + 1
}
相关推荐
海天胜景2 分钟前
C# 中常用的 字符串截取方法
开发语言·c#
why技术1 小时前
翻译翻译,什么叫“编程专用”的显示器?
前端·后端
tkevinjd1 小时前
C++中线程库的基本操作
开发语言·c++
CodeWithMe1 小时前
【C/C++】不同防止头文件重复包含的措施
c语言·开发语言·c++
子豪-中国机器人2 小时前
C++ 信息学奥赛总复习题答案解析
开发语言·c++·算法
oioihoii2 小时前
C++11列表初始化:从入门到精通
java·开发语言·c++
zdy12635746882 小时前
python第48天打卡
开发语言·python
野生技术架构师2 小时前
SpringBoot集成Tess4j :低成本解锁OCR 图片识别能力
spring boot·后端·ocr
whoarethenext2 小时前
使用 C++/OpenCV 创建动态流星雨特效 (实时动画)
开发语言·c++·opencv