rust - 是否有针对 Rc 或 Arc 的操作可以克隆基础值并将其返回给调用者?

标签 rust smart-pointers reference-counting

我正在寻找大致像这样的take,但是是原子的:

impl<T: Clone> for Arc<T> {
    fn take(mut self) -> T {
        Arc::make_mut(&mut self);
        Arc::try_unwrap(self).unwrap()
    }
}

换句话说,我想要 Arc::make_mut 返回值本身,而不是可变引用。

最佳答案

我们可以使用the * deref operator解决 RcArc 内部的基础值,然后调用 .clone() 返回该值的新拥有的克隆(假设它是可克隆的)。

use std::rc::Rc;

fn main() { 
    let rc = Rc::new("Hello".to_string());
    let mut cloned = (*rc).clone();
    cloned.truncate(4);

    // verify that it's modified
    println!("{:?}", cloned); // "Hell"
    // verify that the original was not
    println!("{:?}", rc); // "Hello"
}

Rc/Arc 语义将阻止在您的引用存在时创建任何可变引用,因此此操作是线程安全的;克隆数据时无法更改数据。您也不需要对原始基础值的可变引用,因为您没有修改它。

在某些情况下,Rust 允许您省略 * 解引用运算符:如果您尝试调用指针上不存在的方法,它将隐式解引用一个非可变指针类型,但是确实存在于基础值(value)上。但是,在这种情况下我们需要明确说明,因为 Rc/Arc 上已经存在 .clone() 方法:它用于创建对相同值的新引用。我们不想调用它,因此我们需要显式取消引用以访问内部类型的 .clone()

我们还可以通过适当的类型显式调用它来告诉 Rust 我们想要哪个 .clone() 方法,编译器将根据需要隐式应用尽可能多的取消引用。

use std::rc::Rc;

fn main() { 
    let rc3 = Rc::new(Rc::new(Rc::new("Hello".to_string())));
    let mut cloned = String::clone(&rc3);
    cloned.truncate(4);

    // verify that it's modified
    println!("{:?}", cloned); // "Hell"
    // verify that the original was not
    println!("{:?}", rc3); // "Hello"
}

关于rust - 是否有针对 Rc 或 Arc 的操作可以克隆基础值并将其返回给调用者?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55750616/

相关文章:

c - 是否可以使用C从Rust内置的静态库中调用函数?

rust - 从循环内部向外部范围内的容器存储借来的值?

c++ - 在 C++ 中拥有多个指向单个对象的指针的正确方法是什么?

php - PHP5 中是否引用了字符串?

rust - 借用检查器尝试将函数指针作为参数传递的问题

csv - 使用索引选择是 Polars : How to parse and transform (select/filter? 中的反模式)似乎需要这样的 CSV?

c++ - 共享所有权双重免费错误

c++ - 当重载为类的成员函数时,取消引用运算符 (*) 是如何工作的?

c++ - 将 shared_ptr 分配给自身安全吗?

python - 为什么在 C 中返回 Py_None 之前需要 Py_INCREF(Py_None)?