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
}
相关推荐
CryptoPP2 分钟前
使用WebSocket实时获取印度股票数据源(无调用次数限制)实战
后端·python·websocket·网络协议·区块链
树叶@3 分钟前
Python数据分析7
开发语言·python
wydaicls6 分钟前
十一.C++ 类 -- 面向对象思想
开发语言·c++
白宇横流学长8 分钟前
基于SpringBoot实现的大创管理系统设计与实现【源码+文档】
java·spring boot·后端
草捏子39 分钟前
状态机设计:比if-else优雅100倍的设计
后端
Biomamba生信基地39 分钟前
R语言基础| 下载、安装
开发语言·r语言·生信·医药
姜君竹40 分钟前
QT的工程文件.pro文件
开发语言·c++·qt·系统架构
奇树谦1 小时前
使用VTK还是OpenGL集成到qt程序里哪个好?
开发语言·qt
VBA63371 小时前
VBA之Word应用第三章第十节:文档Document对象的方法(三)
开发语言
老胖闲聊1 小时前
Python Rio 【图像处理】库简介
开发语言·图像处理·python