我想要一个 struct ,Quox
,它可以有 Select 地有每种类型的闭包,可以有(Fn
,FnMut
和FnOnce
).我是这样打的:
#[derive(Default, Debug)]
pub struct Quox<Tfn: Fn(&Person) + Sized, Tfnmut: FnMut(&mut Person) + Sized, Tfnonce: FnOnce(&Person) + Sized> {
soft_closure: Option<Tfn>,
mut_closure : Option<Tfnmut>,
move_closure: Option<Tfnonce>,
}
现在,当实例化它时,我通过Box
来实现它,因为 rust 蚀投诉the trait Sized is not implemented for `dyn Fn()`rustcE0277
.(也许有更好的方法,或者我误解了特征对象?)
pub fn main(){
let mut qx = Quox::<Box<dyn Fn(&Person)>, Box<dyn FnMut(&mut Person)>, Box<dyn FnOnce(&Person)>> {
move_closure: None,
mut_closure : None,
soft_closure: None,
};
...
}
- 真正让我困惑的是,当我创建相应类型的闭包时——为什么我可以随意地将它们赋给
qx
中的字段:
pub fn main(){
let mut qx = Quox::<Box<dyn Fn(&Person)>, Box<dyn FnMut(&mut Person)>, Box<dyn FnOnce(&Person)>> {
move_closure: None,
mut_closure : None,
soft_closure: None,
};
let greeting = "Hi. We are moving soon!".to_string();
let clsr_move = move |p:&Person| println!("Hi, {}. {} says: {}", p.name, p.name, greeting);
let only_a_ref_clsr = |p:&Person| println!("Hi, {}.",p.name );
// qx.move_closure = Some(Box::new(clsr_move)); // expected
// qx.soft_closure = Some(Box::new(only_a_ref_clsr)); // expected
qx.soft_closure = Some(Box::new(clsr_move)); // Why is this valid???
qx.move_closure = Some(Box::new(only_a_ref_clsr)); // Ok Fn is supertrait to FnOnce
}
同样,令人困惑的是,我try 将(似乎)FnMut
分配到Fn
并没有出错.
- 此外为什么现在将
Box
赋给中间变量会引发错误???
pub fn main(){
let mut qx = Quox::<Box<dyn Fn(&Person)>, Box<dyn FnMut(&mut Person)>, Box<dyn FnOnce(&Person)>> {
move_closure: None,
mut_closure : None,
soft_closure: None,
};
let greeting = "Hi. We are moving soon!".to_string();
let clsr_move = move |p:&Person| println!("Hi, {}. {} says: {}", p.name, p.name, greeting);
let only_a_ref_clsr = |p:&Person| println!("Hi, {}.",p.name );
let someboxmove = Some(Box::new(only_a_ref_clsr));
qx.soft_closure = someboxmove; // Invalid.
}
我得到的错误是:
let someboxmove: Option<Box<|&Person| -> ()>>
Go to Option | Box | Person | Global
mismatched types
expected enum `Option<Box<dyn for<'r> Fn(&'r traitobjects::Person)>>`
found enum `Option<Box<[closure@src/traitobjects.rs:49:27: 49:66]>>`rustcE0308
traitobjects.rs(49, 27): the found closure
traitobjects.rs(66, 5): expected due to the type of this binding