我想制作一个指向类方法的全局函数指针,所以我做了如下类似的事情:

struct Foo<'a> {
    data: &'a str,
}

impl<'a> Foo<'a> {
    pub fn foo(&self) {
        println!("{}", self.data);
    }
}

type FooFn = fn(&Foo);

const FUNC: FooFn = Foo::foo;

fn main() {
    let data = String::from("hello");
    let foo = Foo { data: &data };
    FUNC(&foo);
}

Rust Playground

但是rustc给了我一个错误:

$ rustc test.rs
error[E0308]: mismatched types
  --> test.rs:13:21
   |
13 | const FUNC: FooFn = Foo::foo;
   |                     ^^^^^^^^ one type is more general than the other
   |
   = note: expected fn pointer `for<'r, 's> fn(&'r Foo<'s>)`
              found fn pointer `for<'r> fn(&'r Foo<'_>)`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.

这个错误想说什么?我该怎么修?

推荐答案

Rust中的函数指针可以有early-bound个和late-bound个生存期参数.需要在创建函数指针时指定早期绑定生存期参数.仅当指针指向的函数为called时,才指定后期绑定生存期参数,并且每次调用该函数时,该参数都可能不同.

函数指针类型FooFn有两个后期绑定的生存期参数.正如错误消息中所述,它的定义相当于

let FooFn = for<'r, 's> fn(&'r Foo<'s>);

不过Foo::foo的类型不同.只有在完全指定关联函数的类型后,才能查找关联函数.换句话说,self类型的所有生命周期参数都需要提前绑定.这意味着Foo::foo有一个早期绑定和一个晚期绑定生命周期 参数.Foo的生存期参数在创建函数指针时固定,函数指针只能在该特定生存期内调用.编译器在错误消息中将这个尚未确定的生命周期表示为'_.(在这种情况下,'_应该是later be inferred to be 'static,因为这是唯一有意义的固定生命周期 ,但这与这个问题无关.)

有几种方法可以解决这个问题.一种方法是让foo()成为一个免费函数:

fn foo(foo: &Foo) {
    println!("{}", foo.data);
}

另一种方法是将Foo::foo封装在一个简单的闭包中:

const FUNC: FooFn = |f| Foo::foo(f);

这样,我们引用的函数就不再是一个关联函数,所有生命周期参数都可以是后期绑定的.

Rust相关问答推荐

如何处理对打包字段的引用是未对齐错误?

如何初始化match声明中的两个变量而不会激怒borrow 判断器?

当为a Self:IntoIterator设置trait bind `时,获取`a T `不是迭代器"&'"<'>&'

如何从铁 rust 中呼唤_mm_256_mul_ph?

如何将像烫手山芋一样不透明的值从一个Enum构造函数移动到下一个构造函数?

如何为 struct 字段设置新值并在Ruust中的可变方法中返回旧值

如何将映射反序列化为具有与键匹配的字段的定制 struct 的向量?

Rust 的多态现象.AsRef与Derf

为什么TcpListener的文件描述符和生成的TcpStream不同?

JSON5中的变量类型(serde)

使用 serde::from_value 反序列化为泛型类型

一次不能多次borrow *obj作为可变对象

为什么需要静态生命周期以及在处理 Rust 迭代器时如何缩小它?

Button.set_hexpand(false) 不会阻止按钮展开

Rust中的标记特征是什么?

有什么办法可以追踪泛型的单态化过程吗?

错误:将自定义 proc_macro 与用Rust 的宝贝编写的属性一起使用时,无法在此范围内找到属性

为什么基于 clap::Parser 读取的大量数字进行计算比硬编码该数字时慢?

从函数返回 u32 的数组/切片

如何为返回正确类型的枚举实现 get 方法?