Как мне указать параметры типа в качестве аргументов функции в Rust? - PullRequest
4 голосов
/ 06 февраля 2020

Я пытаюсь создать список, который будет содержать Box<dyn Fn(&E)>, где E указано как часть типа. Это работает до тех пор, пока E не содержит ссылку, после чего он начинает запрашивать не относящиеся к жизни времена.

Более простой пример:

pub struct CallbackTest<E> {
    pub cb: Box<dyn Fn(&E)>,
}

impl<E> CallbackTest<E> {
    pub fn new<F>(cb: F) -> Self
    where
        F: Fn(&E)
    {
        Self { cb: Box::new(cb) }
    }
}

pub struct GameData { /* ... */ }

pub type TestRef = CallbackTest<(u32, &GameData)>;

Это дает мне missing lifetime specifier ошибка. Я мог бы поставить параметр времени жизни на TestRef, чтобы заставить его работать, но это не правильный срок жизни. Я не хочу, чтобы &GameData жил в течение всего времени жизни CallbackTest, только во время вызова функции.

РЕДАКТИРОВАТЬ: & GameData является преднамеренным. Это не ошибка. Я надеюсь, что мои изменения сделали цель этого более очевидной.

Любой совет?

1 Ответ

1 голос
/ 06 февраля 2020

Вот мы rust.playground

use std::marker::PhantomData;

pub struct CallbackTest<'a, E, Fa: 'a + Fn(&E)> {
    pub cb: Box<Fa>,
    _e: &'a PhantomData<E>,
}

impl<'a, E, Fa: 'a + Fn(&E)> CallbackTest<'a, E, Fa> {
    pub fn new(cb: Fa) -> Self
    {
        Self { 
            cb: Box::new(cb), 
            _e: &PhantomData
        }
    }
}

pub struct GameData { 
    pub field: i32,
}

pub type TestRef<'a, 'b, Fb> = CallbackTest<'b, (u32, &'a GameData, ), Fb>;

fn main() {
    let game_data = GameData{ field: 42};
    let test_ref: TestRef<_> = CallbackTest::new(|(val, gd): &(u32, &GameData)| { println!("val:{}, field:{}", val, (*gd).field)});
    (test_ref.cb)(&(24, &game_data));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...