Я пытаюсь передать несколько замыканий в структуру и сохранить их как объекты в штучной упаковке. Эти замыкания заключены в многопотоковую (Send, Sync) и клонируемую (Clone) структуру.
use std::thread;
// make trait alias
trait SafeFnMut: FnMut() + Send + Sync {}
impl<F> SafeFnMut for F where F: FnMut() + Send + Sync {}
#[derive(Clone, Debug)]
struct WithCall<F> where F: Sized {
fp: Box<F>,
}
impl<F> WithCall<F> where F: SafeFnMut {
// boxing the closure here
pub fn new(fp: F) -> Self {
WithCall { fp: Box::new(fp) }
}
pub fn run(&mut self) {
(self.fp)()
}
}
struct HasWithCall<T> where T: SafeFnMut {
pub first_fn: Option<Box<WithCall<T>>>,
pub second_fn: Option<Box<WithCall<T>>>,
}
fn main() {
let mut first_fn = WithCall::new(|| {
println!("Called!")
});
let mut second_fn = WithCall::new(|| {
println!("Called other!")
});
let has_with_call = HasWithCall {
first_fn: Some(Box::new(first_fn.clone())),
second_fn: Some(Box::new(second_fn.clone()))
};
println!("{:?}", first_fn.run());
let mut first_fn_a = first_fn.clone();
let mut first_fn_b = first_fn;
let a = thread::spawn(move || {
println!("In remote thread: {:?}", first_fn_a.run());
});
let b = thread::spawn(move || {
println!("In remote thread: {:?}", first_fn_b.run());
});
a.join().expect("Thread A panicked");
b.join().expect("Thread B panicked");
}
Этот код выдает мне следующую ошибку:
error[E0308]: mismatched types --> src/main.rs:39:34
second_fn: Some(Box::new(second_fn.clone()))
^^^^^^^^^^^^^^^^^ expected closure, found a different closure
note: expected type `WithCall<[closure@src/main.rs:29:38: 31:6]>`
found type `WithCall<[closure@src/main.rs:33:39: 35:6]>`
note: no two closures, even if identical, have the same type
help: consider boxing your closure and/or using it as a trait object
I этот вопрос для потоковых безопасных замыканий и этот вопрос для ошибки типа замыкания.
Я вижу, что есть и другие варианты, такие как ссылка напризнак объекта или указатель на функцию. Тем не менее, я хотел бы решить эту проблему с помощью объекта в штучной упаковке, как я уже писал выше.