如何在投射到特征对象时使用 Rc::clone?
How can I use Rc::clone while casting to a trait object?
Rust 书说使用 Rc::clone(&x)
而不是 x.clone()
和 Rc
值是惯用的,所以很明显这不是典型的 clone
。我完全赞成,但我在实践中应用理论时遇到了问题。
我想克隆一个引用计数结构,但将克隆转换为特征对象。我可以使用 rc.clone()
来做到这一点,但 不能 使用 Rc::clone(&rc)
。这对我来说……很奇怪。
struct ListView {}
trait View {}
impl View for ListView {}
fn very_contrived_example() {
let list_view: Rc<ListView> = Rc::new(ListView {});
let mut views: Vec<Rc<dyn View>> = Vec::new();
// Using Rc::clone does not work:
// error[E0308]: mismatched types
//
// views.push(Rc::clone(&list_view));
// ^^^^^^^^^^ expected trait object `dyn View`, found struct `ListView`
//
// note: expected reference `&Rc<dyn View>`
// found reference `&Rc<ListView>`
// Using a cast works in this very contrived example, but has the
// disadvantage of moving `list_view`, for some reason, which is not
// acceptable in general:
// views.push(Rc::clone(&(list_view as Rc<dyn View>)));
// But invoking it using method syntax works fine, without a move:
views.push(list_view.clone());
}
Rc::clone(&x)
和 x.clone()
有什么区别? x.clone()
实际调用的是什么函数? self
的类型是什么?可以直接调用吗?
写这个的惯用方式是什么?
这是一种罕见的类型推断失败。显式传递正确的显式类型有效:
views.push(Rc::<ListView>::clone(&list_view))
问题是 Rc::clone(&list_view)
根据 预期类型 (即 Rc<dyn View>
推断出 Rc<T>
中的 T
), 而不是参数类型。另一方面,当您调用 list_view.clone()
时,它在 list_view
类型上使用 Clone
的实现,因此它解析为 Rc::<ListView>::clone
.
如果上述问题在您的代码中经常出现,并且您希望在视觉上区分普通克隆和引用计数的浅层克隆,您可以编写一些辅助特征:
trait RcClone : Clone {
fn rc_clone(&self) -> Self {
self.clone()
}
}
impl<T: ?Sized> RcClone for Rc<T> { }
impl<T: ?Sized> RcClone for Arc<T> { }
然后您可以在您的代码库中编写 list_view.rc_clone()
,它只适用于引用计数类型。这仍然表明语义不同于常规克隆,同时没有类型推断问题。
Rust 书说使用 Rc::clone(&x)
而不是 x.clone()
和 Rc
值是惯用的,所以很明显这不是典型的 clone
。我完全赞成,但我在实践中应用理论时遇到了问题。
我想克隆一个引用计数结构,但将克隆转换为特征对象。我可以使用 rc.clone()
来做到这一点,但 不能 使用 Rc::clone(&rc)
。这对我来说……很奇怪。
struct ListView {}
trait View {}
impl View for ListView {}
fn very_contrived_example() {
let list_view: Rc<ListView> = Rc::new(ListView {});
let mut views: Vec<Rc<dyn View>> = Vec::new();
// Using Rc::clone does not work:
// error[E0308]: mismatched types
//
// views.push(Rc::clone(&list_view));
// ^^^^^^^^^^ expected trait object `dyn View`, found struct `ListView`
//
// note: expected reference `&Rc<dyn View>`
// found reference `&Rc<ListView>`
// Using a cast works in this very contrived example, but has the
// disadvantage of moving `list_view`, for some reason, which is not
// acceptable in general:
// views.push(Rc::clone(&(list_view as Rc<dyn View>)));
// But invoking it using method syntax works fine, without a move:
views.push(list_view.clone());
}
Rc::clone(&x)
和 x.clone()
有什么区别? x.clone()
实际调用的是什么函数? self
的类型是什么?可以直接调用吗?
写这个的惯用方式是什么?
这是一种罕见的类型推断失败。显式传递正确的显式类型有效:
views.push(Rc::<ListView>::clone(&list_view))
问题是 Rc::clone(&list_view)
根据 预期类型 (即 Rc<dyn View>
推断出 Rc<T>
中的 T
), 而不是参数类型。另一方面,当您调用 list_view.clone()
时,它在 list_view
类型上使用 Clone
的实现,因此它解析为 Rc::<ListView>::clone
.
如果上述问题在您的代码中经常出现,并且您希望在视觉上区分普通克隆和引用计数的浅层克隆,您可以编写一些辅助特征:
trait RcClone : Clone {
fn rc_clone(&self) -> Self {
self.clone()
}
}
impl<T: ?Sized> RcClone for Rc<T> { }
impl<T: ?Sized> RcClone for Arc<T> { }
然后您可以在您的代码库中编写 list_view.rc_clone()
,它只适用于引用计数类型。这仍然表明语义不同于常规克隆,同时没有类型推断问题。