Arc<Mutex function shortcut

Hello,

This question is related to this previous one: Best way to hide borrow_mut - #5 by Alphapage

Here is my new code:

pub struct A {
    pub b: Arc<Mutex<B>>,
}
pub struct B {
    field: C,
}

pub struct C;

trait Update {
    fn update(&mut self, text: C);
}

impl Update for B {
    fn update(&mut self, text: C) {
        self.field = text;
    }
}

impl Update for Arc<Mutex<B>> {
    fn update(&mut self, text: C) {
        self.lock().unwrap().field = text;
    }
}
pub fn try_() {
    let mut a = A {
        b: Arc::new(Mutex::new(B { field: C {} })),
    };
    let closure: Box<dyn Fn()> = Box::new(move || {
        a.b.update(C {});
    });
}

I must use a.b.lock().unwrap().update(C {}); (or change to FnMut but this is no what I want).

I don't understand why it doesn't compile because it is doing the same thing finally!
Is there a workaround ?

Thank you in advance for your help.

In your trait, and the impl for that trait, change:

    fn update(&mut self, text: C) {

to

    fn update(&self, text: C) {

This change allows using an Fn.

You don't need a &mut exclusive reference to a Mutex in order to lock it. The idea of the Mutex is to allow mutation via a & shared reference. That's how a mutable value can be shared between threads.


There is no need for the impl Update for B in your implementation. You could add an update method to B using impl B if you would like, and call that from your trait impl:

    impl B {
        fn update(&mut self, text: C) {
            self.field = text;
        }
    }

    impl Update for Arc<Mutex<B>> {
        fn update(&self, text: C) {
            self.lock().unwrap().update(text);
        }
    }

playground

3 Likes

I wanted to keep implementing the trait for both B and Arc<Mutex...
Thank you :+1:

1 Like