【问题标题】:Implementing trait for Fn(&something) in Rust [duplicate]在 Rust 中实现 Fn(&something) 的 trait [重复]
【发布时间】:2017-05-16 14:00:23
【问题描述】:

这是为Fn() 实现Runnable 的工作示例(这样我们就可以直接将&closure 传递给run_the_runnable 函数):

trait Runnable {
    fn run(&self);
}

impl<F> Runnable for F where F: Fn() {
    fn run(&self) {
        self();
    }
}

fn run_the_runnable(runnable: &Runnable) {
    runnable.run();
}

fn main() {
    // runnable without parameters
    struct MyRunnable;
    impl Runnable for MyRunnable {
        fn run(&self) {
            println!("Hello from MyRunnable");
        }
    }

    // from struct instance (WORKS)
    run_the_runnable(&MyRunnable);

    // from closure (WORKS)
    run_the_runnable(&|| {
        println!("Hello from run() closure");
    });
}

(Rust playground)

现在,让我们将可运行的run() 方法更改为接受引用参数(&amp;i32),并实现Fn(&amp;i32)

trait Runnable {
    fn run(&self, x: &i32);
}

impl<F> Runnable for F where F: Fn(&i32) {
    fn run(&self, x: &i32) {
        self(x);
    }
}

fn run_the_runnable(runnable: &Runnable, x: &i32) {
    runnable.run(x);
}

fn main() {
    // runnable without parameters
    struct MyRunnable;
    impl Runnable for MyRunnable {
        fn run(&self, x: &i32) {
            println!("Hello from MyRunnable {}", x);
        }
    }

    let x = 42;

    // from struct instance (WORKS)
    run_the_runnable(&MyRunnable, &x);

    // from closure (DOES NOT WORK)
    run_the_runnable(&|x| {
        println!("Hello from run(&i32) closure {}", x);
    }, &x);
}

(Rust playground)

传递闭包不再起作用:

error[E0271]: type mismatch resolving `for<'r> <[closure@<anon>:30:27: 32:10] as std::ops::FnOnce<(&'r i32,)>>::Output == ()`
  --> <anon>:30:26
   |
30 |           run_the_runnable(&|x| {
   |  __________________________^ starting here...
31 | |             println!("Hello from run(&i32) closure {}", x);
32 | |         }, &x);
   | |_________^ ...ending here: expected bound lifetime parameter , found concrete lifetime
   |
   = note: concrete lifetime that was found is lifetime '_#63r
   = note: required because of the requirements on the impl of `Runnable` for `[closure@<anon>:30:27: 32:10]`
   = note: required for the cast to the object type `Runnable`

error[E0281]: type mismatch: the type `[closure@<anon>:30:27: 32:10]` implements the trait `std::ops::Fn<(_,)>`, but the trait `for<'r> std::ops::Fn<(&'r i32,)>` is required (expected concrete lifetime, found bound lifetime parameter )
  --> <anon>:30:26
   |
30 |           run_the_runnable(&|x| {
   |  __________________________^ starting here...
31 | |             println!("Hello from run(&i32) closure {}", x);
32 | |         }, &x);
   | |_________^ ...ending here
   |
   = note: required because of the requirements on the impl of `Runnable` for `[closure@<anon>:30:27: 32:10]`
   = note: required for the cast to the object type `Runnable`

关于这个错误有很多问题:

但我仍然无法解决这个特定的生命周期问题。

【问题讨论】:

  • 添加显式类型注释帮助。例如,说&amp;|x: &amp;i32| { ... } 已经解决了问题。在这些情况下,Rust 似乎在推断类型方面存在问题:/ 至少 认为问题是这样的。

标签: rust traits lifetime


【解决方案1】:

正如comment 中所建议的,在闭包参数中给出显式类型可以解决问题:

@@ -26,8 +26,8 @@ fn main() {
     // from struct instance (WORKS)
     run_the_runnable(&MyRunnable, &x);

-    // from closure (DOES NOT WORK)
-    run_the_runnable(&|x| {
+    // from closure with annotated type (WORKS)
+    run_the_runnable(&|x: &i32| {
         println!("Hello from run(&i32) closure {}", x);
     }, &x);
 }

(Rust playground)

【讨论】:

    猜你喜欢
    • 2018-08-02
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 2023-03-26
    • 1970-01-01
    • 2017-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多