我有这个片段:
use std::sync::{Arc, Mutex};
pub struct TaskGroup
{
task_group: Arc<Mutex<Box<dyn Fn() -> dyn Iterator<Item=usize>>>>,
}
impl TaskGroup
{
fn foo(&self)
{
for task in self
.task_group
.lock()
.unwrap()()
{}
}
}
返回:
error[E0618]: expected function, found `MutexGuard<'_, Box<(dyn Fn() -> (dyn Iterator<Item = task::TaskHandle> + 'static) + 'static)>>`
--> crates/thread_pool/src/task.rs:60:25
|
60 | for task in self // task
| _________________________^
61 | | .post_reqs // RwLock
62 | | .read() // handle
63 | | .unwrap() // Ref to TaskGroup
64 | | .task_group // TaskGroup
65 | | .lock()// Mutex lock
66 | | .unwrap()()
| |_________________________^ this trait object returns an unsized value `(dyn Iterator<Item = task::TaskHandle> + 'static)`, so it cannot be called
那么调用框中的函数并获取迭代器的正确方法是什么呢?
问题与以下不起作用的原因相同:
fn f() -> dyn Iterator<Item = usize> {
0..10
}
您试图返回编译时大小未知的内容。如果它是常规的
fn
,那么您可以将 dyn
替换为 impl
,一切都会正常工作。但是,由于您正在处理闭包,因此需要将其装箱。
use std::sync::{Arc, Mutex};
let f: Arc<Mutex<Box<dyn Fn() -> Box<dyn Iterator<Item = usize>>>>> =
Arc::new(Mutex::new(Box::new(|| Box::new((0..10).into_iter()))));
let mut guard = f.lock().unwrap();
let f = guard.as_mut();
for x in f() {
println!("{}", x);
}
记得存放
.lock()
返回的守卫。否则编译器会抱怨临时对象在使用过程中被释放。