4个版本 (2个破坏性更新)

0.5.2 2023年2月14日
0.5.0 2022年8月19日
0.4.0 2022年8月17日
0.3.0 2022年7月27日

#emulate类别中排名第16

Download history 26/week @ 2024-04-01 38/week @ 2024-04-08 32/week @ 2024-05-20 24/week @ 2024-05-27 180/week @ 2024-06-03 4/week @ 2024-06-17

每月下载量:187
用于reborrow

MIT许可证

15KB
266

为用户类型模拟重借用。

泛型引用是指具有引用语义的类型,但实际上不是原生Rust引用(如 &T&mut T)。例如:

struct MyRefMut<'borrow> {
    a: &'borrow mut i32,
    b: &'borrow mut i32,
}

给定一个 &'a [mut] 引用,它是对某个拥有对象的一些拥有视图的 &'b 视图的引用,重借用它意味着获取一个活跃的 &'a 视图,该视图在它被丢弃之前使原始引用无效,此时原始引用再次变为活跃。

此crate定义了特质,通过提供借用和重借用的能力,使泛型引用更容易使用。

功能

derive:此功能导入一个派生宏助手,用于为用户类型实现重借用。它可以与具有相同成员名称的 Ref/RefMut 结构体/元组结构体对一起使用,一个包含共享引用,另一个包含可变引用。共享变体必须是 Copy,宏用于可变变体,并为两种类型生成相关特质。

示例

由于我们无法在移动后使用非 Copy 值,因此此代码无法编译。

fn takes_mut_option(o: Option<&mut i32>) {}

let mut x = 0;
let o = Some(&mut x);
takes_mut_option(o); // `o` is moved here,
takes_mut_option(o); // so it can't be used here.

可以通过展开选项、重借用它,然后再将其包装起来来解决这个问题。

fn takes_mut_option(o: Option<&mut i32>) {}

let mut x = 0;
let mut o = Some(&mut x);
takes_mut_option(o.as_mut().map(|r| &mut **r)); // "Reborrowing" the `Option`
takes_mut_option(o.as_mut().map(|r| &mut **r)); // allows us to use it later on.
drop(o); // can still be used here

使用此crate,可以将此缩短为

use reborrow::ReborrowMut;

fn takes_mut_option(o: Option<&mut i32>) {}

let mut x = 0;
let mut o = Some(&mut x);
takes_mut_option(o.rb_mut()); // "Reborrowing" the `Option`
takes_mut_option(o.rb_mut()); // allows us to use it later on.
drop(o); // can still be used here

派生宏可以与结构体或元组结构体一起使用,并生成 ReborrowReborrowMut 的特质定义。

use reborrow::{ReborrowCopyTraits, ReborrowTraits};

#[derive(ReborrowCopyTraits)]
pub struct I32Ref<'a, 'b> {
    pub i: i32,
    pub j: &'a i32,
    pub k: &'b i32,
}

#[derive(ReborrowCopyTraits)]
pub struct I32TupleRef<'a, 'b>(pub i32, pub &'a i32, pub &'b i32);

#[derive(ReborrowTraits)]
#[Const(I32Ref)]
struct I32RefMut<'a, 'b> {
    i: i32,
    #[reborrow]
    j: &'a mut i32,
    #[reborrow]
    k: &'b mut i32,
}

#[derive(ReborrowTraits)]
#[Const(I32TupleRef)]
pub struct I32TupleRefMut<'a, 'b>(
    i32,
    #[reborrow] &'a mut i32,
    #[reborrow] &'b mut i32,
);

依赖关系

~1.5MB
~35K SLoC