Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to return the value behind an Arc<Mutex<T>> when T doesn't implement Copy?

I’ve been trying to initiate a value (here hashbrown’s hashmap) with the following function:

use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::thread;

#[derive(Clone)]
struct Entity;

fn create_value(center: (f32, f32), length: f32) -> HashMap<(i32, i32), Option<Entity>> {
    let cities: Arc<Mutex<HashMap<(i32, i32), Option<Entity>>>> = Arc::default();
    let mut handles = vec![];

    for i in 0..5 {
        for j in 0..5 {
            let city_thread = Arc::clone(&cities);
            handles.push(thread::spawn(move || {
                // do stuff in parallel
                if let Ok(mut cities) = city_thread.lock() {
                    cities.insert((i, j), None);
                } 
            }));
        }
    }

    for handle in handles {
        handle.join().unwrap();
    }

    // this part is the problem
    if let Ok(city) = cities.lock() {
        let city = city.clone();
        return city;
    } else {
        panic!()
    }
}

I get the following error:

`cities` does not live long enough
the temporary is part of an expression at the end of a block;
consider forcing this temporary to be dropped sooner, before the block's local variables are dropped

I know I’m doing something wrong but I can’t find anything or a way to return the value.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

We need to put the result of city.clone() in a variable that’s declared before the final if let block and move the return out of the if let block as well.

use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::thread;

#[derive(Clone)]
struct Entity;

fn create_value(center: (f32, f32), length: f32) -> HashMap<(i32, i32), Option<Entity>> {
    let cities: Arc<Mutex<HashMap<(i32, i32), Option<Entity>>>> = Arc::default();
    let mut handles = vec![];

    for i in 0..5 {
        for j in 0..5 {
            let city_thread = Arc::clone(&cities);
            handles.push(thread::spawn(move || {
                // do stuff in parallel
                if let Ok(mut cities) = city_thread.lock() {
                    cities.insert((i, j), None);
                }
            }));
        }
    }

    for handle in handles {
        handle.join().unwrap();
    }

    let result;
    if let Ok(city) = cities.lock() {
        result = city.clone();
    } else {
        panic!()
    }

    result
}

Or, we can avoid having the if let be "an expression at the end of a block" by adding a semicolon after it. It’s weird, but it works!

use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::thread;

#[derive(Clone)]
struct Entity;

fn create_value(center: (f32, f32), length: f32) -> HashMap<(i32, i32), Option<Entity>> {
    let cities: Arc<Mutex<HashMap<(i32, i32), Option<Entity>>>> = Arc::default();
    let mut handles = vec![];

    for i in 0..5 {
        for j in 0..5 {
            let city_thread = Arc::clone(&cities);
            handles.push(thread::spawn(move || {
                // do stuff in parallel
                if let Ok(mut cities) = city_thread.lock() {
                    cities.insert((i, j), None);
                } 
            }));
        }
    }

    for handle in handles {
        handle.join().unwrap();
    }

    // this part is the problem
    if let Ok(city) = cities.lock() {
        let city = city.clone();
        return city;
    } else {
        panic!()
    }
    
    ;
}

(I’d recommend the first approach though.)

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading