无法推断一个封闭一辈子返回盒装特征包含参考

问题描述:

我试图编译下面的代码(playground):无法推断一个封闭一辈子返回盒装特征包含参考

trait MockFutureTrait { 
    type Item; 
} 

struct MockFuture<T> { 
    item: T, 
} 

impl<T> MockFutureTrait for MockFuture<T> { 
    type Item = T; 
} 

struct FragMsgReceiver<'a, 'c: 'a> { 
    recv_dgram: &'a FnMut(&mut [u8]) 
     -> Box<MockFutureTrait<Item = &mut [u8]> + 'c>, 
} 

fn constrain_handler<F>(f: F) -> F 
where 
    F: FnMut(&mut [u8]) -> Box<MockFutureTrait<Item = &mut [u8]>>, 
{ 
    f 
} 


fn main() { 
    let mut recv_dgram = constrain_handler(|buf: &mut [u8]| { 
     Box::new(MockFuture { item: buf }) as Box<MockFutureTrait<Item = &mut [u8]>> 
    }); 

    let ref_recv_dgram = &mut recv_dgram; 
    let fmr = FragMsgReceiver { 
     recv_dgram: ref_recv_dgram, 
    }; 
} 

而且我得到的编译错误:

error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements 
    --> src/main.rs:28:37 
    | 
28 |   Box::new(MockFuture { item: buf }) as Box<MockFutureTrait<Item = &mut [u8]>> 
    |          ^^^ 
    | 
note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 27:44... 
    --> src/main.rs:27:44 
    | 
27 |  let mut recv_dgram = constrain_handler(|buf: &mut [u8]| { 
    | ____________________________________________^ 
28 | |   Box::new(MockFuture { item: buf }) as Box<MockFutureTrait<Item = &mut [u8]>> 
29 | |  }); 
    | |_____^ 
note: ...so that expression is assignable (expected &mut [u8], found &mut [u8]) 
    --> src/main.rs:28:37 
    | 
28 |   Box::new(MockFuture { item: buf }) as Box<MockFutureTrait<Item = &mut [u8]>> 
    |          ^^^ 
    = note: but, the lifetime must be valid for the static lifetime... 
note: ...so that expression is assignable (expected std::boxed::Box<MockFutureTrait<Item=&mut [u8]> + 'static>, found std::boxed::Box<MockFutureTrait<Item=&mut [u8]>>) 
    --> src/main.rs:28:9 
    | 
28 |   Box::new(MockFuture { item: buf }) as Box<MockFutureTrait<Item = &mut [u8]>> 
    |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 

我试图添加各种生命提示,但我无法获得此代码进行编译。在SO这个

我以前的相关问题:

请注意,我用的根据建议,我在问题2拿到了辅助函数constrain_handler;它允许我克服不同的编译错误。

+0

我从来没有见过一个答案[我评论你的原始问题](https://*.com/questions/46194930/lifetime-problems-with-struct-containing-function-reference#comment79358569_46194930)关于为什么你希望这是一个关闭无论如何的参考。 – Shepmaster

+0

@shepmaster:还有其他方法可以做到吗?我想要做的是采用基于数据报的套接字,并将其封装在一个新的类型中,这将允许我发送和接收抽象数据报(这些数据报与底层数据报之间没有1-1对应关系)。因此我参考了'recv_dgram'函数。 – real

看来,你已经错过了你以前的问题,它们的副本的关键外卖:

通过在封闭声明类型论点,你停止执行类型推断的参数。这会导致封闭生成新的隐式生命周期,这与您的要求不符。只是不要声明类型。

接下来,你需要指出你的闭包要采取一些字节的引用,并返回一个盒装特质的对象,将返回相同的寿命的一些字节,并包含相同的寿命的参考:

struct FragMsgReceiver<'a> { 
    recv_dgram: &'a for<'b> FnMut(&'b mut [u8]) 
     -> Box<MockFutureTrait<Item = &'b mut [u8]> + 'b>, 
} 

有关+ 'a语法的更多详细信息,请参阅Why is Box<Iterator<Item = &Foo> + 'a> needed?

然后更新constrain_handler匹配:

struct FragMsgReceiver<'a> { 
    recv_dgram: &'a for<'b> FnMut(&'b mut [u8]) 
     -> Box<MockFutureTrait<Item = &'b mut [u8]> + 'b>, 
} 

fn constrain_handler<F>(f: F) -> F 
where 
    F: for<'b> FnMut(&'b mut [u8]) 
     -> Box<MockFutureTrait<Item = &'b mut [u8]> + 'b>, 
{ 
    f 
} 

fn main() { 
    let mut recv_dgram = constrain_handler(|buf| Box::new(MockFuture { item: buf })); 

    let fmr = FragMsgReceiver { 
     recv_dgram: &mut recv_dgram, 
    }; 
} 

整个事情可以变得更简单,如果你只是需要一个通用的关闭直接:

struct FragMsgReceiver<R> 
where 
    R: for<'b> FnMut(&'b mut [u8]) 
     -> Box<MockFutureTrait<Item = &'b mut [u8]> + 'b>, 
{ 
    recv_dgram: R, 
} 

fn main() { 
    let fmr = FragMsgReceiver { 
     recv_dgram: |buf| Box::new(MockFuture { item: buf }), 
    }; 
} 
+0

你的'FragMsgReceiver'的第一个定义和第二个定义(你在where子句中使用'R'的地方有区别吗? – real

+0

@real yes - 它不再是对特质对象的引用(注意缺少'&'a'),而是一种泛型类型,它将被单态化。 – Shepmaster

+0

我不知道这是可能的。那么现在FragMsgReceiver的大小取决于封闭的大小?整个封闭存储在FragMsgReceiver内部吗? – real