当Rust结构包含生命特征时会发生什么?

Tec*_*out 2 traits lifetime rust

好的,所以我是一个完整的Rust新手,我正在试验Rocket.该Web框架传递了一个Form<MyStruct>,我想将MyStruct传输到我自己的自定义结构中.

struct Consumer<T> {
    d: T,
}

impl<T> Consumer<T> {
   fn new(form: Form<T>) -> Self {
       Consumer { d: form.into_inner() }
   }
}
Run Code Online (Sandbox Code Playgroud)

当然,这不起作用,我得到:

the trait `rocket::request::FromForm<'_>` is not implemented for `T`
Run Code Online (Sandbox Code Playgroud)

下一次尝试:

impl<T> Consumer<T> where T: FromForm {
    fn new(form: Form<T>) -> Self {
        Consumer { d: form.into_inner }
    }
}
Run Code Online (Sandbox Code Playgroud)

哦哦:

impl<T> Consumer<T> where T: FromForm {
                             ^^^^^^^^ expected lifetime parameter
Run Code Online (Sandbox Code Playgroud)

所以现在我发现自己完全无法解决这个问题!我能想到的最好的是:

impl<'f, T> Consumer<T> where T: FromForm<'f> {
    fn new(form: Form<T>) -> Self {
        Consumer { d: form.into_inner }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是这导致了这个错误:

51 |           fn new(form: Form<T>) -> Self {                                                                                      
   |  _________^                                                                                                                    
52 | |             Consumer { d: form.into_inner }                                                                                  
53 | |         }                                                                                                                    
   | |_________^ lifetime mismatch
  = note: expected type `rocket::request::FromForm<'_>`                                                                            
             found type `rocket::request::FromForm<'f>`
Run Code Online (Sandbox Code Playgroud)

可验证的示例:https://hastebin.com/eqihaqodux.makefile

Pet*_*all 5

Form也有一个生命周期参数.如果你将它与生命周期联系起来FromForm,那么你将向前推进一点:

impl<'f, T> Consumer<T> where T: FromForm<'f> {
    fn new(form: Form<'f, T>) -> Self {
        Consumer(form.into_inner())
    }

    fn get(&self) -> &T {
        &self.0
    }
}
Run Code Online (Sandbox Code Playgroud)

作为一般规则,如果您返回一个依赖于另一个对象中的数据的对象,那么您需要像这样将它们的生命周期链接在一起.

此时,您将看到另一个错误,它可以方便地为您提供修复它所需的所有信息:

error[E0310]: the parameter type `T` may not live long enough
  --> src/main.rs:50:17
   |
48 | impl<'f, T> Consumer<T> where T: FromForm<'f> {
   |          - help: consider adding an explicit lifetime bound `T: 'static`...
49 |     fn new(form: Form<'f, T>) -> Self {
50 |         Consumer(form.into_inner())
   |                       ^^^^^^^^^^
   |
note: ...so that the type `T` will meet its required lifetime bounds
  --> src/main.rs:50:17
   |
50 |         Consumer(form.into_inner())
   |                       ^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)

into_inner上方法Form要求它的类型参数T具有'static寿命,并且该错误消息建议加入此约束.

通过这些更改,它将编译:

impl<'f, T: 'static> Consumer<T> where T: FromForm<'f> {
    fn new(form: Form<'f, T>) -> Self {
        Consumer(form.into_inner())
    }

    fn get(&self) -> &T {
        &self.0
    }
}
Run Code Online (Sandbox Code Playgroud)