rust - 指向带有生命周期参数的方法的函数指针的类型

标签 rust

我有一个带有生命周期和一些方法的结构:

struct Ctrl<'a> {
    x: &'a i32,
}

impl<'a> Ctrl<'a> {
    fn foo(&self) -> i32 {
        *self.x + 1
    }
    fn bar(&self) -> i32 {
        *self.x + 2
    }
}

现在我想将指向方法的指针存储在一个切片中,有点像查找表:

const LIST: &[_] = &[Ctrl::foo, Ctrl::bar];

Rust 要求知道切片元素类型并建议 for<'r> fn(&'r Ctrl) -> i32 ,但这会导致错误:

error[E0308]: mismatched types
  --> main.rs:16:48
   |
16 | const LIST: &[for<'r> fn(&'r Ctrl) -> i32] = &[Ctrl::foo, Ctrl::bar];
   |                                                ^^^^^^^^^ one type is more general than the other
   |
   = note: expected fn pointer `for<'s, 'r> fn(&'r Ctrl<'s>) -> _`
              found fn pointer `for<'r> fn(&'r Ctrl<'_>) -> _`

有没有办法指定正确的类型?

最佳答案

问题是 fooCtrl<'x> 的一种方法对于一些特定的生命周期'x ,而不是一个通用的方法Ctrl<'_> .如果你试图让所有的生命周期都显式化,你会发现有些生命周期是无法表达的:

const LIST: &[for<'a, 'b> fn(&'b Ctrl<'a>) -> i32] = &[Ctrl::<'?>::foo, Ctrl::<'?>::bar)];
//                                          What lifetimes?  ^^^^             ^^^^

foo不是通用的,但绑定(bind)到特定的 Ctrl<'_> ,没有办法表达你需要的概念。你可以尝试像 <for<'a> Ctrl<'a>>::foo 这样的东西,但这在当前的 Rust 中是不合法的。

解决这个问题的一种方法是将每个方法包装在一个可以强制转换为函数指针的闭包中:

const LIST: &[fn(&Ctrl<'_>) -> i32] = &[|this| this.foo(), |this| this.bar()];

如果您有很多方法或签名更复杂,这可能会有点冗长。另一种选择是将每个方法包装在一个具有正确签名的自由函数中。您可以编写声明性宏以使其更容易:

/// Wrap `Ctrl::$method` in a free function and return it.
macro_rules! ctrl {
    ($method:ident) => {{
        fn inner(this: &Ctrl<'_>) -> i32 {
            this.$method()
        }
        inner
    }};
}

const LIST: &[fn(&Ctrl<'_>) -> i32] = &[ctrl!(foo), ctrl!(bar)];

关于rust - 指向带有生命周期参数的方法的函数指针的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64102352/

相关文章:

rust - 是否需要在使用时导入特征?

rust - GnuCOBOL 调用 Rust : libcob: error: module not found

rust - 如何在不使用 Tokio 同时运行相同功能的情况下以重复间隔同时运行一组功能?

pointers - Rust 中的指针转换是否与 C++ 中的 reinterpret_cast 具有相同的行为?

docker - Rust musl Docker 镜像找不到 Cargo

string - 通过正则表达式拆分字符串以获得 Vec<String>

rust - 当毯子将公共(public)特征实现为私有(private)特征时,公共(public)接口(interface)中的私有(private)特征

rust - 无法编译允许将值插入其中的 OneOrMany 枚举

rust - Rust 模式匹配如何确定绑定(bind)变量是引用还是值?

rust - 如何查看 TcpStream 并阻塞直到有足够的字节可用?