【问题标题】:How to define a pointer to a trait function in Rust如何在 Rust 中定义指向特征函数的指针
【发布时间】:2021-03-28 17:39:25
【问题描述】:

如果我的问题已经得到解答或在文档中的某处,我深表歉意,但我无法找到答案。假设我有以下代码:

trait Saluter {
    fn hello(&self);
    fn bye(&self);
}

struct A {}
struct B {}

impl Saluter for A {
    fn hello(&self) {
        println!("Hello A!");
    }

    fn bye(&self) {
        println!("Bye A!");
    }
}

impl Saluter for B {
    fn hello(&self) {
        println!("Hello B!");
    }

    fn bye(&self) {
        println!("Bye B!");
    }
}

pub struct Foo {
    saluter: Box<dyn Saluter>,
    salute: fn (&dyn Saluter),
}

fn main() {
    let x = Foo {saluter: Box::new(A{}), salute: Saluter::hello};
    let y = Foo {saluter: Box::new(B{}), salute: Saluter::bye};
    (x.salute)(x.saluter.borrow()); //Should print "Hello A!"
    (y.salute)(y.saluter.borrow()); //Should print "Hello B!"
}

基本上我试图独立地操纵调用者和被调用的方法。但是我得到以下编译错误:

let x = Foo {saluter: Box::new(A{}), salute: Saluter::hello};
   |                                                  ^^^^^^^^^^^^^^ one type is more general than the other
   |
   = note: expected fn pointer `for<'r> fn(&'r (dyn Saluter + 'r))`
              found fn pointer `for<'r> fn(&'r dyn Saluter)`

同样的错误显然适用于 y。我最近才开始学习 Rust,所以我对 Rust 生命周期参数一点也不流利,但在我看来,它在抱怨这一点,尽管我找不到 (dyn Salute + 'r) 的确切含义。

有没有办法实现我想要的,或者这在 Rust 中根本不可能?在 C++ 中,我可以轻松地使用指向 Base 类的指针来做到这一点,但我正在努力寻找如何在 Rust 中实现这一点。

感谢您的帮助!

【问题讨论】:

    标签: rust function-pointers traits


    【解决方案1】:

    您在 Foo 结构中使用由 Saluter 绑定的泛型类型:

    pub struct Foo<T> where T: Saluter {
        saluter: Box<T>,
        salute: fn (&T),
    }
    

    Playground

    【讨论】:

    【解决方案2】:

    我能够通过仅约束函数指针类型来编译您的代码:

    pub struct Foo {
        saluter: Box<dyn Saluter>,
        salute: fn (&(dyn Saluter + 'static)),
    }
    

    这个额外的+ 'static 约束意味着存储在Foo 中的salute 函数指针只能与实现Saluter 的类型一起使用,这些类型没有有限的生命周期——松散地说, “不包含非静态引用”。也就是说,如果你有

    struct B<'x> { ... }
    impl<'x> Saluter for B<'x> {}
    

    那么该功能将无法使用。但是,这种情况并不常见。

    不幸的是,我不确定为什么函数指针 Saluter::hello 不能是原始代码所暗示的完全通用类型,

        salute: for<'a> fn (&'a (dyn Saluter + 'a)),
    

    所以我无法给出完整的解释。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-27
      • 2014-05-03
      • 2011-12-17
      • 2019-01-21
      • 1970-01-01
      • 2017-01-05
      • 1970-01-01
      相关资源
      最近更新 更多