Как сделать Fn (T) + «статическим регистром как» статическим для любого аргумента универсального типа T? - PullRequest
0 голосов
/ 29 декабря 2018

Я использую ящик для спецификаций , который имеет черту Component, которая расширяет черту std::any::Any (черта Any требует только 'static).Я хочу включить поле Box<Fn(T) + 'static> (с общим аргументом T) в структуру, для которой реализовано Component, что означает, что Box<Fn(T) + 'static> должно быть 'static.Это означает, что мне нужно Fn(T) + 'static, чтобы быть 'static для любого T.

Кажется, Fn(T) + 'static не 'static для любого аргумента универсального типа T.T может ссылаться на структуру со своими собственными временами жизни, но я ожидал, что это не будет проблемой, потому что в Fn нет экземпляра ссылки с этими временами жизни, чтобы сам по себе Fn не 'static -эти времена жизни содержатся только в аргументах, передаваемых Fn, но считается, что Fn(T) + 'static содержит само T.

Пример:

struct HandlesT<T> {
    handler: Box<Fn(T) + 'static>,
}

impl<T> HandlesT<T> {
    pub fn new<F: Fn(T) + 'static>(handler: F) -> HandlesT<T> {
        HandlesT {
            handler: Box::new(handler),
        }
    }
}

trait IsStatic: 'static {}
impl<T> IsStatic for HandlesT<T> {}
error[E0310]: the parameter type `T` may not live long enough
  --> src/lib.rs:14:9
   |
14 | impl<T> IsStatic for HandlesT<T> {}
   |      -  ^^^^^^^^
   |      |
   |      help: consider adding an explicit lifetime bound `T: 'static`...
   |
note: ...so that the type `HandlesT<T>` will meet its required lifetime bounds
  --> src/lib.rs:14:9
   |
14 | impl<T> IsStatic for HandlesT<T> {}
   |         ^^^^^^^^

В этом примере, поскольку HandlesT<T> вообще не содержит нестатических ссылок для любых заданных T (вообще никаких ссылок, кроме тех, которые принадлежат Fn, но они должны быть 'static), я ожидал HandlesT<T> должно быть статическим для любого T, но ошибка указывает, что это не так.

Предложение компилятора «рассмотреть возможность добавления явной границы времени жизни T: 'static» не поддерживает ни аргумент универсального типа T, нидает подсказки о том, почему HandlesT<T> для любого универсального T не является 'static, учитывая, что HandlesT<T> не будет содержать T.

Пример T: 'static (предложение компилятора) неподдерживая любой общий T, вэтот случай &'a i32:

struct HandlesT<T: 'static> {
    handler: Box<Fn(T) + 'static>,
}

impl<T: 'static> HandlesT<T> {
    pub fn new<F: Fn(T) + 'static>(handler: F) -> HandlesT<T> {
        HandlesT {
            handler: Box::new(handler),
        }
    }
}

trait IsStatic: 'static {}
impl<T: 'static> IsStatic for HandlesT<T> {}

fn try_nonstatic_t<'a>() {
    let handles_t = HandlesT {
        handler: Box::new(|i: &'a i32| {}),
    };
}
error[E0477]: the type `&'a i32` does not fulfill the required lifetime
  --> src\lib.rs:17:21
   |
17 |     let handles_t = HandlesT {
   |                     ^^^^^^^^
   |
   = note: type must satisfy the static lifetime
...