在结构中指定函数指针类型的生命周期

Fab*_*orr 5 function-pointers lifetime rust

我有一个foo定义如下的函数:

fn foo<'a>(a: &'a i32, b: &i32) -> &'a i32 { a }
Run Code Online (Sandbox Code Playgroud)

我想在结构中存储指向该函数的指针:

struct S {
    f: fn(a: &i32, b: &i32) -> &i32,
}
Run Code Online (Sandbox Code Playgroud)

因为有两个输入生命周期,所以无法推断结果生命周期:

error[E0106]: missing lifetime specifier
  |
2 |     f: fn(a: &i32, b: &i32) -> &i32,
  |                                ^ expected lifetime parameter
  |
  = help: this function's return type contains a borrowed value,
    but the signature does not say whether it is borrowed from a or b
Run Code Online (Sandbox Code Playgroud)

当我问编译器foo的类型时,它也不是很有帮助:

let () = foo;
Run Code Online (Sandbox Code Playgroud)

给我

expected type `fn(&'a i32, &i32) -> &'a i32 {foo}`
Run Code Online (Sandbox Code Playgroud)

这显然不起作用,因为'a没有在任何地方定义.

那么如何在此上下文中声明生命周期?尝试其中之一

f: fn<'a>(a: &'a i32, b: &i32) -> &'a i32
f<'a>: fn(a: &'a i32, b: &i32) -> &'a i32
Run Code Online (Sandbox Code Playgroud)

导致语法错误,我找不到涵盖这种特定情况的文档.

She*_*ter 6

定义结构体的生命周期:

fn foo<'a>(a: &'a i32, b: &i32) -> &'a i32 { a }

struct S<'b, 'c> {
    f: fn(a: &'b i32, b: &'c i32) -> &'b i32,
}

fn main() {
    S {
        f: foo,
    };
}
Run Code Online (Sandbox Code Playgroud)

请注意,在此上下文中您无法忽略第二生命周期。

但这意味着对 的调用在和 的(s.f)(&x, &y)生命周期内不再是通用的,不像abfoo(&x, &y)

然后你需要更高等级的特征界限(HRTB):

fn foo<'a>(a: &'a i32, _b: &i32) -> &'a i32 { a }

struct S<F>
    where for <'b, 'c> F: Fn(&'b i32, &'c i32) -> &'b i32,
{
    f: F,
}

fn main() {
    S {
        f: foo,
    };
}
Run Code Online (Sandbox Code Playgroud)

  • 值得一提的是,hrtb 语法适用于函数指针类型,如 `f: for&lt;'a,'b&gt; fn(a: &amp;'a i32, b: &amp;'b i32) -&gt; &amp;'a i32`。 (6认同)