0

Is there a clean way to implement a safe function g that mutates a mutable reference by applying f on its value without having to implement Clone or Default (or any other special trait) for T? If not, why is or should this not be possible?

Imagine a type T and a function f:

fn f(v: T) -> T;

For example:

fn f(mut v: u32) -> u32 {
    v += 1;
    v
}

The following code is invalid because p cannot be dereferenced:

fn g(p: &mut T) {
    *p = f(*p)
}

I searched and tried many things, but I didn't come up with a safe solution.


For people who are interested for the cases where Clone and Default are allowed:

  • By implementing Clone you could do:

    fn g(p: &mut T) {
        *p = f(p.clone())
    }
    
  • By implementing Default you could do:

    fn g(p: &mut T) {
        let val = core::mem::take(p);
        core::mem::replace(p, f(val));
    }
    
Natrix
  • 113
  • 6
  • 1
    TL;DR: No, there is not. – Shepmaster Feb 12 '20 at 02:40
  • Could you try to describe the flow or scenario in which you'd want to do this instead of this hypothetical? – AdaShoelace Feb 12 '20 at 07:53
  • @Stargateur Could you please clarify which part of the question you consider unclean @MasterBait I've got a Window-Trait, that has a function `draw` that should return a type that implements my Draw-Trait and is living maximum as long as the window. The Window-Trait should specify which Draw-Type to use. But now it is not possible to deliver that Window::Draw a lifetime. However it is possible to consume Window and return a Draw-Object that is back-convertible into the Window. This function would be analog to `f` in my question. But I'd also like to have a function in `g`-style. – Natrix Feb 13 '20 at 12:11
  • @Natrix could be better but you fix it in your last edit – Stargateur Feb 13 '20 at 20:23
  • this message is for ping @MasterBait because natrix try to ping you but comment can only ping one person – Stargateur Feb 13 '20 at 20:24

0 Answers0