ruststructmutable

How to update a collection inside a struct in rust?


Probably this question already has been asked, maybe with different wording, but I couldn't find it. If this gets closed due to this, apologies, but I did try before.

In fact, the problem is simple:

use std::collections::BTreeSet;

pub struct Service {
    blobs: BTreeSet<u16>,
}

impl Service {
    fn new() -> Self {
        let bt: BTreeSet<u16> = BTreeSet::new();
        Self { blobs: bt }
    }

    fn insert(&self, val: u16) -> bool {
        &self.blobs.insert(val);
        true
    }
    fn print(&self) {
        println!("{}", self.blobs.len());
    }
}
fn main() {
    let s: Service = Service::new();
    s.print();
    s.insert(4);
    s.print();
}

When compiling this, I get:

`self` is a `&` reference, so the data it refers to cannot be borrowed as mutable

What I understand here, is that actually, I can't just update the treeset, as it's immutable.

So I tried with

pub struct Service {
    blobs: &'static mut BTreeSet<u16>,
}

and

  fn new() -> Self {
        let bt: &mut BTreeSet<u16> = &mut BTreeSet::new();
        Self { blobs: bt }
    }

but that yields creates a temporary value which is freed while still in use (while the original error is still there, so now I have two...)

I understand I should somehow make the BTreeSet mutable, but how?


Solution

  • Most of the time the error message just tell you how to fix the code, all hail rust compiler.

    PS *******************> cargo run --bin mess_around
       Compiling mess_around v0.1.0 (*******************)
    error[E0596]: cannot borrow `self.blobs` as mutable, as it is behind a `&` reference
      --> mess_around\src/main.rs:14:9
       |
    14 |         self.blobs.insert(val)
       |         ^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
       |
    help: consider changing this to be a mutable reference
       |
    13 |     fn insert(&mut self, val: u16) -> bool {
       |               ~~~~~~~~~
    
    For more information about this error, try `rustc --explain E0596`.
    error: could not compile `mess_around` (bin "mess_around") due to 1 previous error
    

    Fixed

    use std::collections::BTreeSet;
    
    pub struct Service {
        blobs: BTreeSet<u16>,
    }
    
    impl Service {
        fn new() -> Self {
            let bt: BTreeSet<u16> = BTreeSet::new();
            Self { blobs: bt }
        }
    
        fn insert(&mut self, val: u16) -> bool {
            self.blobs.insert(val)
        }
        fn print(&self) {
            println!("{}", self.blobs.len());
        }
    }
    fn main() {
        let mut s: Service = Service::new();
        s.print();
        s.insert(4);
        s.print();
    }