[英]Cannot infer a lifetime for a closure returning a boxed trait that contains a reference
I am trying to compile the following code ( playground ): 我正在尝试编译以下代码( 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,
};
}
And I get the compile error: 我得到了编译错误:
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]>>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I tried to add various lifetime hints, but I couldn't get this code to compile. 我试图添加各种生命周期提示,但是无法编译此代码。
My previous related questions on SO about this: 我之前在SO上与此相关的问题:
Cannot infer a lifetime for a struct containing a reference to a closure : Solving the same problem, when the return value is a simple struct and not a trait. 无法推断出包含对闭包的引用的结构的生存期 :如果返回值是简单结构而不是特征,则可以解决相同的问题。
How can multiple struct fields be generics that use the same higher-kinded lifetime? 多个结构字段如何成为使用相同寿命的泛型的泛型? : About trying to solve this problem without Boxes.
:关于尝试不使用Box来解决此问题。 The answer suggests that for now I will have to use Box>.
答案表明,现在我将不得不使用Box>。
Note that I am using the helper function constrain_handler
according to a suggestion I got in question 2; 注意,我根据问题2的建议使用了辅助函数
constrain_handler
。 it allows me to overcome a different compilation error. 它使我能够克服一个不同的编译错误。
It appears that you've missed a key takeaway of your previous questions and their duplicates: 您似乎错过了先前问题及其重复内容的关键要点:
By declaring a type on the closure argument, you stop performing type inference for the arguments. 通过在闭包参数上声明类型,可以停止对参数执行类型推断 。 This causes a new implicit lifetime to be generated by the closure, one which does not match your requirements.
这将导致闭包生成新的隐式生存期,这与您的要求不符。 Just don't declare the type at all.
只是根本不声明类型。
Next, you need to state that your closure is going to take a reference to some bytes and return a boxed trait object that will return some bytes of the same lifetime and contains a reference of that same lifetime: 接下来,您需要声明您的闭包将要引用一些字节,并返回一个装箱的特征对象,该对象将返回一些具有相同生存期的字节,并包含具有相同生存期的引用:
struct FragMsgReceiver<'a> {
recv_dgram: &'a for<'b> FnMut(&'b mut [u8])
-> Box<MockFutureTrait<Item = &'b mut [u8]> + 'b>,
}
See Why is Box<Iterator<Item = &Foo> + 'a> needed? 请参阅为什么需要Box <Iterator <Item =&Foo> +'a>? for more details about the
+ 'a
syntax. 有关
+ 'a
语法的更多详细信息。
Then update constrain_handler
to match: 然后更新
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,
};
}
The whole thing can be made simpler if you just take a generic closure directly: 如果您直接采用通用闭包,则可以简化整个过程:
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 }),
};
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.