如何调用存储在 Box 中的 dyn 函数?

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

我有这个片段:

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

那么调用框中的函数并获取迭代器的正确方法是什么呢?

generics rust function-pointers traits
1个回答
0
投票

问题与以下不起作用的原因相同:

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()
返回的守卫。否则编译器会抱怨临时对象在使用过程中被释放。

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