暂时改变不可变结构

问题描述 投票:0回答:1

我正在尝试创建类似于下面代码的内容。鉴于我只是暂时修改不可变结构(我撤消了所做的更改),这样转换原始指针是否安全?

#[derive(Debug)]
struct Num(i32); // doesn't impl Copy

// prints one more than the input num
fn modify_read_undo(num: &Num) {
    let num_ptr = num as *const Num as *mut Num; // the scary part
    unsafe {
        (*num_ptr).0 += 1;
        println!("{:?}", *num_ptr);
        (*num_ptr).0 -= 1;
    }
}

fn main() {
    let num = Num(0);
    modify_read_undo(&num); // prints "Num(1)" as hoped for
}

在这个小例子中,一切似乎都按其应有的方式工作,但我担心这是某种未定义的行为,只是目前恰好在工作。如果只需要一个不可变的引用,这种函数是否可能?如果不是,如何实现类似的模式(修改、读取、撤消)?

我知道如果我使用可变引用或只是取得所有权,这可能会起作用 - 我特别感兴趣的是使用不可变引用(以满足特征边界)来使其工作。如果有必要,我可以发布完整的代码,但这个示例很好地演示了我想要的内容。

注意:有没有办法使不可变引用可变?类似,但不完全相同,因为它们永久更改不可变结构,而我在进行更改后立即撤消更改。

rust immutability mutability
1个回答
0
投票

这是一个使用

RefCell
的简单示例:

use std::cell::RefCell;

#[derive(Debug)]
struct Num(RefCell<i32>); // Use RefCell for interior mutability

// The function takes an immutable reference
fn modify_read_undo(num: &Num) {
    {
        // Borrow the value mutably inside this scope
        let mut num_borrowed = num.0.borrow_mut();
        *num_borrowed += 1;
        // The mutable borrow ends here, so the next line is safe
    }

    // Print the value
    println!("{:?}", num);

    {
        // Borrow the value mutably again to undo the change
        let mut num_borrowed = num.0.borrow_mut();
        *num_borrowed -= 1;
    }
}

fn main() {
    let num = Num(RefCell::new(0));
    modify_read_undo(&num);

    // The original value of num is preserved
    println!("{:?}", num); // prints "Num(RefCell { value: 0 })"
}

© www.soinside.com 2019 - 2024. All rights reserved.