我一直在尝试使用以下函数启动一个值(这里是 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
我知道我做错了什么,但我找不到任何东西或方法来返回该值。
我们需要将
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!()
}
;
}
(不过我推荐第一种方法。)