[SOLVED] Yet another problem with borrowed value lifetime in iterator


#1

Hello,

I am trying to compile following code:

use std::sync::{Arc, Mutex};

struct Indexes {
    a: &'static str,
    b: f32,
}

struct Worker {
    indexes: Arc<Mutex<Box<Vec<Indexes>>>>
}

impl Worker {
    fn handle_get_data(&self) {
        for entry in self.indexes.lock().unwrap().iter_mut() {
            // modify self.indexes
        }
    }
}

fn main() {
    let mut worker = Worker {
        indexes: Arc::new(Mutex::new(Box::new(Vec::new()))),
    };
    worker.handle_get_data();
}

And get following error:

<anon>:14:22: 14:50 error: borrowed value does not live long enough
<anon>:14         for entry in self.indexes.lock().unwrap().iter_mut() {
                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
<anon>:14:9: 16:10 note: reference must be valid for the for at 14:8...
<anon>:14         for entry in self.indexes.lock().unwrap().iter_mut() {
<anon>:15             // modify self.indexes
<anon>:16         }
<anon>:14:22: 14:50 note: ...but borrowed value is only valid for the method call at 14:21
<anon>:14         for entry in self.indexes.lock().unwrap().iter_mut() {
                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~

I don’t quite understand where problem arises. It has something to do with self.*, but not clue what rustc dislikes. I don’t see which borrowed value is short-living.

My goal is to iterate over the vector which is a member of certain “class”, and modify vector data on-the-fly. Box is required as I want this vector data to be on the heap, as it is going to contain huge strings, will be modified frequently, and will contain lots of members. And mutex required as it supposed to work in nickel-based web-server and has to do with concurrency.


#2

I’m not sure what exactly is the problem here (to much indirection maybe? :slight_smile: ), but removing a Box which seems completely unnecessary helps:

use std::sync::{Arc, Mutex};

struct Indexes {
    a: &'static str,
    b: f32,
}

struct Worker {
    indexes: Arc<Mutex<Vec<Indexes>>>
}

impl Worker {
    fn handle_get_data(&self) {
        let mut indexes = self.indexes.lock().unwrap();
        for entry in indexes.iter_mut() {
            // modify self.indexes
        }
    }
}

fn main() {
    let mut worker = Worker {
        indexes: Arc::new(Mutex::new(Vec::new())),
    };
    worker.handle_get_data();
}

Box is not necessary because Vec data always lives on the heap. The size of vector itself is just three pointers.


#3

Interesting, that helped.

Thanks a lot!