由于通用型锈蚀的寿命,无法从关闭中返回关闭

问题描述 投票:0回答:1

我是 Rust 的新手,我正在尝试将库从 kotlin 重写为 Rust。它是回调事件库。当尝试从另一个闭包返回闭包时,它会破坏

on_event
注册回调的函数,并且还会破坏调用函数,该调用函数由于调用者泛型中的生命周期而获取调用函数。我在很多论坛上问过这个问题,却得不到帮助。

代码

lib.rs

mod event;

#[cfg(test)]
mod tests {
    use crate::event::*;
    fn test(mut x: i32,y: i32, entries: &[&dyn Fn(i32)]) -> i32 {
        for entry in entries {
            x *= 3;
            (entry)(x);
        }
        x * y
    }
    fn invoker<'a>(entries: &'a [&'a dyn Fn(i32)]) -> impl Fn(i32) -> i32 + 'a {
        move |y|test(1,y,&entries)
    }
    #[test]
    fn it_works() {
        let mut event_test = EventKey::new(invoker);
        let test = &|x: i32| {
            println!("Hello {}", x);
        };
        event_test.on_event(test);
        event_test.on_event(test);
        event_test.on_event(test);
        let result = event_test.invoke()(10);
        assert_eq!(result, 270);
    }
}

事件.rs

/// Event file
/// I - invoker type
/// R - additional return type
/// C - Callback arguments
/// Please know that this applies to everything in this file

pub struct EventKey<I, C> {
    invoker: I,
    callbacks: Vec<C>
}

impl<I,C,R> EventKey<I,C>
where I: Fn (&[C]) -> R
{
    pub fn new(invoker: I) -> EventKey<I, C> {
        EventKey {
            invoker,
            callbacks: Vec::new()
        }
    }

    pub fn on_event(&mut self, callback: C) {
        self.callbacks.push(callback);
    }

    pub fn invoke(&self) -> R {
        (self.invoker)(&self.callbacks)
    }
}

错误

  1. 没有生命周期
error[E0700]: hidden type for `impl Fn(i32) -> i32` captures lifetime that does not appear in bounds
  --> src/lib.rs:14:9
   |
13 |     fn invoker(entries: &[&dyn Fn(i32)]) -> impl Fn(i32) -> i32 {
   |                         --------------- hidden type `[closure@src/lib.rs:14:9: 14:17]` captures the anonymous lifetime defined here
14 |         move |y|test(1,y,&entries)
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
help: to declare that `impl Fn(i32) -> i32` captures `'_`, you can introduce a named lifetime parameter `'a`
   |
13 |     fn invoker<'a>(entries: &'a [&'a dyn Fn(i32)]) -> impl Fn(i32) -> i32 + 'a  {
   |               ++++           ++   ++                                      ++++
  1. 有生命周期
error[E0599]: the method `on_event` exists for struct `EventKey<for<'a> fn(&'a [&'a (dyn Fn(i32) + 'a)]) -> impl Fn(i32) -> i32 + 'a {invoker}, &dyn Fn(i32)>`, but its trait bounds were not satisfied
  --> src/lib.rs:22:20
   |
22 |         event_test.on_event(test);
   |                    ^^^^^^^^ method cannot be called due to unsatisfied trait bounds
   |
  ::: src/event.rs:7:1
   |
7  | pub struct EventKey<I, C> {
   | ------------------------- method `on_event` not found for this struct
   |
note: the following trait bounds were not satisfied:
      `<for<'a> fn(&'a [&'a (dyn Fn(i32) + 'a)]) -> impl Fn(i32) -> i32 + 'a {invoker} as FnOnce<(&[&dyn Fn(i32)],)>>::Output = _`
      `for<'a> fn(&'a [&'a (dyn Fn(i32) + 'a)]) -> impl Fn(i32) -> i32 + 'a {invoker}: Fn<(&[&dyn Fn(i32)],)>`
  --> src/event.rs:13:10
   |
12 | impl<I,C,R> EventKey<I,C>
   |             -------------
13 | where I: Fn (&[C]) -> R
   |          ^^^^^^^^^^^^^^
   |          |            |
   |          |            unsatisfied trait bound introduced here
   |          unsatisfied trait bound introduced here
   = note: the following trait bounds were not satisfied:
           `for<'a> fn(&'a [&'a (dyn Fn(i32) + 'a)]) -> impl Fn(i32) -> i32 + 'a {invoker}: FnMut<(&[&dyn Fn(i32)],)>`
           which is required by `for<'a> fn(&'a [&'a (dyn Fn(i32) + 'a)]) -> impl Fn(i32) -> i32 + 'a {invoker}: Fn<(&[&dyn Fn(i32)],)>`
           `for<'a> fn(&'a [&'a (dyn Fn(i32) + 'a)]) -> impl Fn(i32) -> i32 + 'a {invoker}: FnOnce<(&[&dyn Fn(i32)],)>`
           which is required by `for<'a> fn(&'a [&'a (dyn Fn(i32) + 'a)]) -> impl Fn(i32) -> i32 + 'a {invoker}: Fn<(&[&dyn Fn(i32)],)>`
events rust types callback lifetime
1个回答
0
投票

如果你确定

test
中的
it_works
是正确的类型:

let test: &dyn Fn(i32) = &|x| {
    println!("Hello {}", x);
};

您必须在实现中注释生命周期以匹配您的使用:

impl<I, C> EventKey<I, C> {
    pub fn new(invoker: I) -> EventKey<I, C> {
        EventKey {
            invoker,
            callbacks: Vec::new(),
        }
    }

    pub fn on_event(&mut self, callback: C) {
        self.callbacks.push(callback);
    }

    pub fn invoke<'a, R>(&'a self) -> R
    where
        I: Fn(&'a [C]) -> R + 'a,
        R: 'a,
        C: 'a,
    {
        (self.invoker)(&self.callbacks)
    }
}

注意:在正确注释生命周期后,编译器会抱怨

R
不受约束,这是理所当然的,为了修复它,我移动了边界和类型参数以仅应用于
invoke
方法。

© www.soinside.com 2019 - 2024. All rights reserved.