无法推断一个封闭一辈子返回盒装特征包含参考
我试图编译下面的代码(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这个
我以前的相关问题:
Cannot infer a lifetime for a struct containing a reference to a closure:解决同样的问题,当返回值是一个简单的结构,而不是一个特质。
How can multiple struct fields be generics that use the same higher-kinded lifetime?:关于试图解决这个问题没有框。答案表明,现在我将不得不使用Box>。
请注意,我用的根据建议,我在问题2拿到了辅助函数constrain_handler
;它允许我克服不同的编译错误。
看来,你已经错过了你以前的问题,它们的副本的关键外卖:
- Lifetime annotation for closure argument
- Cannot infer a lifetime for a struct containing a reference to a closure
- How to declare a lifetime for a closure argument
通过在封闭声明类型论点,你停止执行类型推断的参数。这会导致封闭生成新的隐式生命周期,这与您的要求不符。只是不要声明类型。
接下来,你需要指出你的闭包要采取一些字节的引用,并返回一个盒装特质的对象,将返回相同的寿命的一些字节,并包含相同的寿命的参考:
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 }),
};
}
你的'FragMsgReceiver'的第一个定义和第二个定义(你在where子句中使用'R'的地方有区别吗? – real
@real yes - 它不再是对特质对象的引用(注意缺少'&'a'),而是一种泛型类型,它将被单态化。 – Shepmaster
我不知道这是可能的。那么现在FragMsgReceiver的大小取决于封闭的大小?整个封闭存储在FragMsgReceiver内部吗? – real
我从来没有见过一个答案[我评论你的原始问题](https://stackoverflow.com/questions/46194930/lifetime-problems-with-struct-containing-function-reference#comment79358569_46194930)关于为什么你希望这是一个关闭无论如何的参考。 – Shepmaster
@shepmaster:还有其他方法可以做到吗?我想要做的是采用基于数据报的套接字,并将其封装在一个新的类型中,这将允许我发送和接收抽象数据报(这些数据报与底层数据报之间没有1-1对应关系)。因此我参考了'recv_dgram'函数。 – real