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
@MatthieuMFnMut
事情并不总是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()
}
}