在Rust中如何将类型参数指定为函数参数?

4

我正在尝试创建一个列表,其中包含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)>;

这使我得到了一个“缺少生命周期说明符”的错误。 我可以TestRef上放置一个生命周期参数来让它工作,但那不是正确的生命周期。 我不想让&GameDataCallbackTest的整个生命周期内都存在,只需要在函数调用期间存在。
编辑:&GameData是有意的,这不是一个错误。 我希望我的更改能够更清楚地表达背后的目标。
有什么建议吗?

正如@Stargateur所说,我认为这是因为您错误地向u32添加了另一个引用层。在这种情况下,编译器要求寿命是正确的。 - Boiethios
&u32 是有意为之的。我将其更改为更明确地表明我正在尝试传递一个包含多个值的元组,其中一个是引用。 - BinderNews
很抱歉,您的编辑使这个句子有些含糊不清:我不想让&u32在整个CallbackTest的生命周期中都存在,只需要在函数调用期间存在。 @ÖmerErden的建议对您有帮助吗? - trent
我的错,不行。问题似乎在于我不能使CallbackTest对函数参数进行泛型化。 - BinderNews
1个回答

1

这里是 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));
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接