如何将一个字段的生存期指定为其他字段的组合?

HBe*_*Bex 3 lifetime rust

我有一个函数,该函数在三个引用字段中的结构中存储两个参数。我不知道如何指定此第三个结果字段的生存期,这是该函数的前两个参数的生存期的组合。

我尝试将前两个参考参数存储在结构中。这工作得很好,没有意义。我在下面显示的情况更有趣,我没有解决方案。

我知道这段代码没有任何意义;它只是显示问题。

// This function can be found in "Lifetime Annotations in Function Signatures" of the Rust manual
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

// Here comes the interesting part; 1st the result type of my function
struct SillyResult<'a, 'b, 'c> {
    arg1: &'a str,
    arg2: &'b str,
    result: &'c str,
}

// ... and now the function, that does not compile and shall be corrected
fn silly_fkt<'a, 'b, 'c: 'a + 'b>(arg1: &'a str, arg2: &'b str) -> SillyResult<'a, 'b, 'c> {
    // Neither the following line ...
    // SillyResult<'a, 'b, 'c>{arg1: arg1, arg2: arg2, result: longest(arg1, arg2)}
    // ... nor the following line work
    SillyResult {
        arg1,
        arg2,
        result: longest(arg1, arg2),
    }
}
Run Code Online (Sandbox Code Playgroud)

这个想法是将终生'a'b终生相结合'c。但是,它给出了很多关于生命周期的错误信息:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'a in function call due to conflicting requirements
  --> src/lib.rs:25:17
   |
25 |         result: longest(arg1, arg2),
   |                 ^^^^^^^^^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the lifetime 'b as defined on the function body at 18:18...
  --> src/lib.rs:18:18
   |
18 | fn silly_fkt<'a, 'b, 'c: 'a + 'b>(arg1: &'a str, arg2: &'b str) -> SillyResult<'a, 'b, 'c> {
   |                  ^^
note: ...so that reference does not outlive borrowed content
  --> src/lib.rs:25:31
   |
25 |         result: longest(arg1, arg2),
   |                               ^^^^
note: but, the lifetime must be valid for the lifetime 'c as defined on the function body at 18:22...
  --> src/lib.rs:18:22
   |
18 | fn silly_fkt<'a, 'b, 'c: 'a + 'b>(arg1: &'a str, arg2: &'b str) -> SillyResult<'a, 'b, 'c> {
   |                      ^^
   = note: ...so that the expression is assignable:
           expected SillyResult<'a, 'b, 'c>
              found SillyResult<'_, '_, '_>
Run Code Online (Sandbox Code Playgroud)

我试图将的最后一行更改silly_fkt

SillyResult<'a, 'b, 'c>{ arg1, arg2, result: longest(arg1, arg2) }
Run Code Online (Sandbox Code Playgroud)

但这不起作用。

正确的代码是silly_fkt什么?

tre*_*tcl 5

您具有:向后的语义:'c: 'a表示'c outlives 'a,您要在此位置说其'c 寿命过长 'a(以便您可以提供生命周期的引用,'a在该引用中'c预期存在生命周期)。因此,您需要以其他方式编写生存期约束。

您可以编写<'a: 'c, 'b: 'c, 'c>,但是我发现使用where子句更容易阅读:

fn silly_fkt<'a, 'b, 'c>(arg1: &'a str, arg2: &'b str) -> SillyResult<'a, 'b, 'c>
where
    'a: 'c,
    'b: 'c,
{
    SillyResult {
        arg1,
        arg2,
        result: longest(arg1, arg2),
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我发现将生存期视为时间间隔,并将冒号视为“包含”很有用。这里的约束意味着“ c”包含在“ a”和“ b”的交点中。(当然,“包含”的含义与“寿命”完全相同,但是它可以帮助我以不同的方式可视化寿命。) (4认同)