当T没有实现Copy时,如何返回Arc后面的值<Mutex<T>>?

问题描述 投票:0回答:1

我一直在尝试使用以下函数启动一个值(这里是 hashbrown 的哈希图):

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!()
    }
}

我收到以下错误:

`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

我知道我做错了什么,但我找不到任何东西或方法来返回该值。

rust concurrency
1个回答
0
投票

我们需要将

city.clone()
的结果放入在最终 if let 块之前
声明的变量中,并将 
return
 移出 
if let
 块。

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 }
或者,我们可以通过在 

if let

 后面添加分号来避免它成为“块末尾的表达式”。这很奇怪,但它有效!

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!() } ; }
(不过我推荐第一种方法。)

© www.soinside.com 2019 - 2024. All rights reserved.