简体   繁体   中英

Rust calling mutable self function from mutable self function

In the example below, I want to call spin for every smol_socket_handle which is simply an usize .

pub fn spin_all(&mut self) -> u8 {
        for (smol_socket_handle, _) in self.smol_sockets.iter_mut() {
            self.spin(smol_socket_handle.clone());
        }
        0
    }
pub fn spin(&mut self, smol_socket_handle: usize) -> u8 {

The problem is that I borrow self as mutable twice. Once when spin_all is called, and once again when we call spin . I absolutely need spin to work on a &mut self . How can I make spin_all call spin lots of times for a mutable self ?

UPDATE:

So if I understood correctly,

    for (smol_socket_handle, smol_socket) in self.smol_sockets.iter_mut() {
        self.spin(smol_socket_handle.clone());
    }

expands into

{
    //borrows self mutably
    let mut _iter = std::iter::IntoIterator::into_iter(self.smol_sockets.iter_mut());
    loop {
        match _iter.next() {
            Some(loop_variable) => {
                //tries to borrow self mutably again while it's still borrowed into `_iter`
                self.spin(loop_variable.clone());
            },
            None => break,
        }
    }
}

?

The problem is that I borrow self as mutable twice. Once when spin_all is called, and once again when we call spin.

No, that is not the problem. The mutable &mut self of spin_all is reused by spin , there is no conflict (in fact it would not work otherwise, as self.spin would try to create a mutable borrow from an immutable borrow, which would fail).

The problem is that you're creating a mutable borrow for self.smol_sockets.iter_mut() , and a separate and overlapping borrow for self.spin() .

You should either avoid the borrow on the sockets iterable by cloning it as Aloso noted, or give spin an index / key into the iterable so that it does the borrowing internally.

Simplest answer for me was to declare the mutable borrows in the second function. If foo calls bar , do the mutable borrowing inside bar instead of passing bar a mutable reference, which doesn't work.

Do this:

pub fn foo(&mut self, thingid: u32) {
    //stuff
    self.bar(&thingid);
}
pub fn bar(&mut self, thingid: u32) {
    self.things.get_mut(&thingid).unwrap();
    //stuff
}

Don't do this as it causes an error ( error[E0502]: cannot borrow *self as immutable because it is also borrowed as mutable ).

pub fn foo(&mut self, thingid: u32) {
    //stuff
    let thing = self.things.get_mut(&thingid).unwrap();
    self.bar(thing);
}
pub fn bar(&mut self, thing: &mut Thing) {
    //stuff
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM