关于rust:是否存在Rc或Arc的操作,该操作会克隆基础值并将其返回给调用方?

Is there an operation for Rc or Arc which clones the underlying value and returns it to the caller?

我正在寻找大致类似于take的东西,但是是原子的:

1
2
3
4
5
6
impl<T: Clone> for Arc< T > {
    fn take(mut self) -> T {
        Arc::make_mut(&mut self);
        Arc::try_unwrap(self).unwrap()
    }
}

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


我们可以使用*的deref运算符来寻址RcArc内部的基础值,然后调用.clone()以返回该值的新拥有的克隆(假定它是可克隆的) )。

1
2
3
4
5
6
7
8
9
10
11
12
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允许您省略* deref运算符:如果尝试调用指针上不存在但在指针上存在的方法,它将隐式取消引用非可变指针类型。基本价值。但是,在这种情况下,我们需要明确说明,因为Rc / Arc上已经存在.clone()方法:该方法用于创建对相同值的新引用。我们不想调用它,因此我们需要显式取消引用来访问内部类型的.clone()

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

1
2
3
4
5
6
7
8
9
10
11
12
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"
}