Pass a mutable reference into function

pub struct Item {
    
}

pub struct Configuration {
    pub items: Vec<Item>,
}


lazy_static! {
    static ref CONFIG: RwLock<Configuration> = RwLock::new(Configuration::default());
}


pub fn update<F>(func: F) -> Result<(), Box<dyn std::error::Error>>
    where F: FnMut(&mut Configuration) 
{
    let writer = CONFIG.write().unwrap();
    let cfg : &mut Configuration = &mut writer;
    func(cfg);

    Ok(())
}

I have the code above, now I want to update the items in CONFIG

update(|cfg : &mut Configuration| {
    for (i, item) in (&cfg.items).iter().enumerate() {
        cfg.items.remove(i); 
        ^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
    }
})

Please how to fix this issue? thank you.

remove requires a mutable reference while the Iterator takes an immutable reference. If you just want to empty the vector I would suggest to simply call cfg.items.clear().

In other cases, retain might be useful.

To update vector elements in place, use iter_mut instead of iter.

What you're trying to do here is called iterator invalidation error. It's not acceptable in any languages. In C++ it would silently corrupt your memory, in Java it would throws exception, and in Rust it would fails to compile.

The cfg.items.iter() methods returns an iterator over shared references of elements in the vector. To do so, it contains a shared reference of the vector itself. Due to the aliasing rule, it effectively prevents to take a unique reference(&mut) to the vector so you can't modify it during the iterator is alive.

4 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.