[Idea] Improving the ergonomics when using Rc

Regarding ergonomics there are other paths that would be more lightweight while remaining explicit:

  • Custom macros:
macro_rules! rc_vec {
  (
    $($expr:expr),*
  ) => (
    vec![ $(::std::rc::Rc::clone(&$expr), )* ]
  );
}

and then use rc_vec![foo, bar, baz]. This way, any reader can know something special is happening since the classic vec macro is not the one being used.

  • A macro-less solution would be to use iterators:
let vec: Vec<Rc<_>> =
  [&foo, &bar, &baz]
    .iter()
    .map(|&x| x.clone())
    .collect();

Both may seem more cumbersome but scale better.

If you are writing you own function, you can then require that the arguments be references to Rcs (and clone them in the first line of the function’s body) so that calling those functions just requires to write &foo instead of foo.clone().

I think that any “easier” or more lightweight way would do more harm than good, since implicitness is the very footgun that rust fights against.

3 Likes