Hello everyone! When using Rc, I found myself often required to call clone() explicitly and this hurts ergonomics a lot.
use std::rc::Rc;
pub trait Widget {}
#[derive(Clone, Copy)]
pub struct Foo(u32);
impl Widget for Foo {}
#[derive(Clone, Copy)]
pub struct Bar(f32);
impl Widget for Bar {}
pub struct Row {
children: Vec<Rc<Widget>>,
}
fn main() {
let foo = Rc::new(Foo(1));
let bar = Rc::new(Bar(2.5));
let row1 = Row {
children: vec![foo.clone(), bar.clone()],
};
let row2 = Row {
children: vec![bar, foo],
};
fn take_copyable(_v: Vec<Foo>) {}
let f = Foo(0);
// no need to call clone if T: Copy
take_copyable(vec![f, f, f, f]);
}
Most of the cases explicitly calling clone is preferred to indicate there are something expensive operations. However, some type’s clone is lightweight and ergonomics is preferred.
Therefore, similar to primitive type implement Copy, should we introduce ImplicitClone trait for ergonomics when using some type, e.g. Rc?
trait ImplicitClone: Clone {
fn implicit_clone(&self) -> Self;
}
impl<T> ImplicitClone for Rc<T> {
fn implicit_clone(&self) -> Self {
self.clone()
}
}
fn main() {
let foo = Rc::new(Foo(1));
let bar = Rc::new(Bar(2.5));
let row1 = Row {
// Rc<Foo>, Rc<Boo> implement ImplicitClone, no need to call clone explicitly
children: vec![foo, bar],
};
let row2 = Row {
children: vec![bar, foo],
};
}