当前位置: 首页 > article >正文

Rust~Pin的new

Pin::new(&mut my_struct) 中传了一个 MyStruct 实例的引用,但是 Pin::new 需要的参数又是 Ptr,这种转换是怎么做到的
注意,区别于其他语言,Ptr 是一个范型,<Ptr: Deref<Target: Unpin>>

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 方法的要求进行必要的解引用,最终匹配到合适的类型。

示例

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 标准库中,其核心目的是为类型提供可变解引用的能力

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 类型的值时,编译器会自动进行解引用操作。

示例

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
}

http://www.kler.cn/a/568947.html

相关文章:

  • 【git】【rebase】git修改提交信息的几种方法
  • 【AI Coding】Windsurf:【Prompt】全局规则与项目规则「可直接使用」
  • 如何在 ArcGIS Pro 中将SHP转为KML:详细步骤与操作指南
  • 基于互联网协议的诊断通信(DoIP)
  • 《HarmonyOS Next × ArkTS框架:从AI模型压缩到智能家居控制的端侧开发指南》
  • 对rust中的from和into的理解
  • Android 应用开发中,证书、签名和加固简述
  • 加入二极管的NE555 PWM 电路
  • Go在1.22版本修复for循环陷阱
  • RJ45网口 与 M12连接器对比(D-code,X-code)
  • 面试常见问题
  • UDP接收方法使用Task替代Thread(解决关闭程序未响应的问题)
  • Flink事件时间和处理时间咋区分
  • yolov8_pose模型,使用rknn在安卓RK3568上使用
  • 深入解析 MySQL 中的时间函数:NOW() 与 SYSDATE() 的奥秘
  • TCP的四次挥⼿为什么是四次?为什么不能是三 次
  • 【计算机网络——概述】
  • 深搜专题7:最大质数
  • 【基于Raft的KV共识算法】-序:Raft概述
  • JavaEE基础之- 过滤器和监听器Filter and Listener