Rust 有克洛涅姆特的特征吗?

Rust 有克洛涅姆特的特征吗?,rust,clone,borrow-checker,Rust,Clone,Borrow Checker,clone()的一个容易被忽略的特性是,它可以缩短隐藏在被克隆的值中的任何引用的生命周期。这对于不可变引用通常是无用的,不可变引用是唯一一种实现了Clone的引用 然而,能够缩短隐藏在值中的可变引用的生命周期将非常有用。是否有类似于克隆人的特质 我设法写了一本。我的问题是,我是否应该使用标准库中的一个特性,即我是否在重新发明轮子 这个问题的其余部分包括细节和例子 特殊情况:类型是可变引用 作为一个预热,当您要克隆的类型是可变引用,而不是以任何方式包装时,以下内容就足够了: fn clone_m

clone()
的一个容易被忽略的特性是,它可以缩短隐藏在被克隆的值中的任何引用的生命周期。这对于不可变引用通常是无用的,不可变引用是唯一一种实现了
Clone
的引用

然而,能够缩短隐藏在值中的可变引用的生命周期将非常有用。是否有类似于克隆人的特质

我设法写了一本。我的问题是,我是否应该使用标准库中的一个特性,即我是否在重新发明轮子

这个问题的其余部分包括细节和例子

特殊情况:类型是可变引用 作为一个预热,当您要克隆的类型是可变引用,而不是以任何方式包装时,以下内容就足够了:

fn clone_mut<'a, 'b: 'a>(q: &'a mut &'b mut f32) -> &'a mut f32 {
    *q
}
下面是一个调用方示例:

fn main() {
    let mut x: f32 = 3.142;
    let mut p = Foo(&mut x);
    {
        let q = p.clone_mut();
        *q.0 = 2.718;
    }
    println!("{:?}", *p.0)
}
请注意,除非
q
p
获得更短的生存期,否则这不会编译。我想将其视为
clone\u mut()
的单元测试

高级类型? 当试图编写一个同时支持上述两种实现的trait时,这个问题一开始感觉像是一个更高级类型的问题。例如,我想写以下内容:

trait CloneMut {
    fn clone_mut<'a, 'b>(self: &'a mut Self<'b>) -> Self<'a>;
}

impl CloneMut for Foo {
    fn clone_mut<'a, 'b>(self: &'a mut Self<'b>) -> Self<'a> {
        Foo(self.0)
    }
}
但是,它与调用者不兼容,因为它没有两个不同的生存期变量

error[E0502]:无法将“*p.0”作为不可变项借用,因为“p”也作为可变项借用
错误消息中提到的不可变借用是
println!()
语句,可变借阅是对
clone\u mut()的调用。
。这种特性限制两个生命周期是相同的

尝试2 这使用与尝试1相同的特征定义,但使用不同的实现:

trait CloneMut<'a> {
    fn clone_mut(&'a mut self) -> Self;
}

impl<'a, 'b: 'a> CloneMut<'a> for Foo<'b> {
    fn clone_mut(&'a mut self) -> Self {
        Foo(self.0)
    }
}

这就是为什么我认为“
CloneMut
”是个好名字。

引用
&mut
的关键属性是它们是唯一的独占引用


所以它不是真正的克隆。您不能有两个独占引用。这是一个重新箭头,因为只要“克隆”在范围内,源代码将完全不可用。

CloneMut
太难理解了。在我看来,引用基本上只在一个层次上有用,你不应该试图通过嵌套它们或将它们相互分配来实现更复杂的东西。我不会称之为
CloneXXX
,因为可变引用不是
Clone
@MatthieuM
FnMut
事情并不总是
Fn
,但我们对“
FnMut
”感到满意。我想你需要一个更好的理由。图恩德是另一个候选人。它具有关联的类型,并对其进行绑定以将其与Self类型关联。然而,在我的情况下,这个界限并不满足(你不能通过借钱来延长寿命),所以我猜这也是错误的。似乎有关联。
trait CloneMut<'a> {
    type To: 'a;

    fn clone_mut(&'a mut self) -> Self::To;
}

impl<'a, 'b> CloneMut<'a> for Foo<'b> {
    type To = Foo<'a>;

    fn clone_mut(&'a mut self) -> Self::To {
        Foo(self.0)
    }
}
trait CloneMut<'a> {
    fn clone_mut(&'a mut self) -> Self;
}

impl<'a> CloneMut<'a> for Foo<'a> {
    fn clone_mut(&'a mut self) -> Self {
        Foo(self.0)
    }
}
trait CloneMut<'a> {
    fn clone_mut(&'a mut self) -> Self;
}

impl<'a, 'b: 'a> CloneMut<'a> for Foo<'b> {
    fn clone_mut(&'a mut self) -> Self {
        Foo(self.0)
    }
}
trait CloneMut {
    fn clone_mut<'a>(&'a mut self) -> Self;
}

impl<'b> CloneMut for Foo<'b> {
    fn clone_mut<'a>(&'a mut self) -> Self {
        Foo(self.0)
    }
}
impl<'a, T: 'a> CloneMut<'a> for T where T: Clone {
    type To = Self;

    fn clone_mut(&'a mut self) -> Self {
        self.clone()
    }
}