我正在尝试编写一个函数返回一个盒装闭包,它可以处理对任何生命周期的类型的引用.在编写特定实例时,一切正常.但是在编写通用版本时,我会遇到终身问题.
struct Parameter<'a> {
s: &'a str,
}
fn main() {
let closure = generate_closure_gen();
let string = String::from("Hello World!");
let parameter = Parameter { s: &string }; // Error: string does not live long enough
closure(¶meter);
}
// This one works fine
// Desugared version for Box<Fn(&Parameter)>
fn generate_closure() -> Box<for <'a, 'r> Fn(&'r Parameter<'a>)> {
Box::new(|c: &Parameter| {})
}
// This one gives lifetime errors
fn generate_closure_gen<C>() -> Box<Fn(&C)> {
Box::new(|c: &C| {})
}
Run Code Online (Sandbox Code Playgroud)
我不明白为什么闭包需要类型参数比它更长寿(没有存储或任何东西......).它适用于具有HRTB的非通用版本,它只是觉得应该可以使它与泛型版本一起使用.
此外,如果我尝试使用通用版本编写特定版本,我会收到类型错误
// Desugared …Run Code Online (Sandbox Code Playgroud) 在结构中使用traits作为类型参数时,我遇到了借用检查器的问题:
trait Trait {}
struct FooBar;
impl Trait for FooBar{}
struct Observer<Arg> {
action: Box<Fn(Arg) + Send>,
// Other fields
}
impl <Arg> Observer<Arg> {
fn new(action: Box<Fn(Arg) + Send>) -> Observer<Arg> {
Observer{action: action}
}
fn execute(&self, arg: Arg) {
(*self.action)(arg);
}
}
fn test() {
let mut foobar = FooBar;
{
let mut observer = Observer::new(Box::new(|&: param: &mut Trait| {
// do something with param here
}));
observer.execute(&mut foobar); // First borrow passes ...
observer.execute(&mut foobar); // This …Run Code Online (Sandbox Code Playgroud)