簡體   English   中英

被 Rust 閉合壽命弄糊塗了

[英]Confused by Rust closure lifetime

我遇到了一個令人困惑的情況,編譯器輸出的內容在邏輯上沒有意義。 這是重現我在項目代碼中遇到的相同問題的最小示例。

use std::sync::Arc;

struct A<'a, T> {
    f: Box<dyn Fn(&u32) -> T + 'a>
}

struct B<'a> {
    inner: A<'a, Z<'a>>
}

impl<'a, T> A<'a, T> {
    fn new<F>(f: F) -> Self where F: Fn(&u32) -> T + 'a {
        A { f: Box::new(f) }
    }
}

struct X<'a> {
    _d: &'a std::marker::PhantomData<()>
}

struct Z<'a> {
    _d: &'a std::marker::PhantomData<()>
}

impl<'a> X<'a> {
    fn g(&self, y: u32) -> Z {
        Z { _d: &std::marker::PhantomData }
    }
}

impl<'a> B<'a> {
    fn new(x: Arc<X<'a>>) -> Self {
        B {
            inner: A::new(move |y: &u32| -> Z {
                x.g(*y)
            })
        }
    }
}

fn main() {
}

還有令人困惑的編譯錯誤:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
  --> t.rs:35:19
   |
35 |                 x.g(*y)
   |                   ^
   |
note: first, the lifetime cannot outlive the lifetime '_ as defined on the body at 34:27...
  --> t.rs:34:27
   |
34 |             inner: A::new(move |y: &u32| -> Z {
   |                           ^^^^^^^^^^^^^^^^^^^
note: ...so that closure can access `x`
  --> t.rs:35:17
   |
35 |                 x.g(*y)
   |                 ^
note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 31:6...
  --> t.rs:31:6
   |
31 | impl<'a> B<'a> {
   |      ^^
   = note: ...so that the expression is assignable:
           expected B<'a>
              found B<'_>

error: aborting due to previous error

我不太明白的是日志中提到的“生命周期”指的是什么,以及匿名生命周期'_究竟代表什么。

您的代碼中有一個小疏忽。 它應該是:

impl<'a> X<'a> {
    fn g(&self, y: u32) -> Z<'a> {
        Z { _d: &std::marker::PhantomData }
    }
}

整個事情然后編譯。 這是 Rust 的生命周期省略規則發揮作用的一個例子。

根據相關的省略規則,即:

  • 輸入 position 中每個省略的生命周期成為一個不同的生命周期參數。
  • 如果有多個輸入生命周期位置,但其中之一是&self&mut self ,則將self的生命周期分配給所有省略的 output 生命周期。

然后要rustc ,您的原始代碼實際上將如下所示:

impl<'a> X<'a> {
    fn g<'b>(&'b self, y: u32) -> Z<'b> {
        Z { _d: &std::marker::PhantomData }
    }
}

省略的生命周期參數'b將來自調用站點,這正是您在錯誤消息中看到的。 rustc無法調和這兩個生命周期,因此出現錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM