简体   繁体   English

无法推断闭包的寿命,该闭包返回包含引用的盒装特征

[英]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上与此相关的问题:

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.

相关问题 无法为返回引用的闭包推断合适的生命周期 - Cannot infer an appropriate lifetime for a closure that returns a reference Rust – 从 trait 方法返回 trait 对象时无法推断出适当的生命周期 - Rust – cannot infer an appropriate lifetime when returning trait object from trait method 在结构中存储闭包 - 无法推断出适当的寿命 - Storing a closure in a structure — cannot infer an appropriate lifetime 在实现Deref特征时无法推断生命周期参数的适当生命周期 - Cannot infer an appropriate lifetime for lifetime parameter while implementing Deref trait 无法推断生命周期参数克隆特征对象的适当生命周期 - Cannot infer an appropriate lifetime for lifetime parameter cloning trait object 尝试在返回迭代器的闭包内改变状态时,Rust 错误“无法推断借用表达式的适当生命周期” - Rust error "cannot infer an appropriate lifetime for borrow expression" when attempting to mutate state inside a closure returning an Iterator 使用闭包返回对枚举变体内容的引用时,“无法推断适当的生命周期” - "cannot infer an appropriate lifetime" when using a closure to return a reference to an enum variant's content 传递盒装特征作为参考 - Pass boxed trait as a reference 将结构转换为具有生存期的特征得到“由于需求冲突,无法为生存期参数&#39;a&#39;推断适当的生存期” - casting struct to trait with lifetime got “cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements” 如何将生存期参数添加到闭包而不返回引用 - How to add lifetime argument to closure not returning a reference
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM