gpt4 book ai didi

rust - 在结构中存储具有生命周期的闭包

转载 作者:行者123 更新时间:2023-11-29 08:07:45 25 4
gpt4 key购买 nike

我正在尝试将闭包存储在 Vec 中那是结构的一部分。闭包是一个工厂函数,它接收 2 个引用作为参数并生成一个特征对象,该对象存储闭包接收的引用作为参数。

因此,生成的特征对象的生命周期不得超过引用的生命周期。还有 component_registrations将从多个线程访问,因此包装在 Arc<Mutex> 中.

我尝试实现它,但编译器说通用参数 Fregister_component函数不满足 component_registrations 中使用的特征界限.

这是代码的相关部分:

use std::sync::Mutex;
use std::sync::Arc;

pub mod gl {
pub struct Gl();
}

pub struct ComponentRegistry<'a> {
gl: &'a gl::Gl
}

pub trait Component<'a> {
}

pub struct Application {
component_registrations: Arc<Mutex<Vec<Box<for<'b> Fn(&'b ComponentRegistry<'b>, &'b gl::Gl) -> Box<Component<'b>> + Send + 'static>>>>
}

impl Application {
pub fn new() -> Application {
Application {
component_registrations: Arc::new(Mutex::new(vec![]))
}
}

pub fn register_component<'a, F>(&mut self, register: F) where F: Fn(&'a ComponentRegistry<'a>, &'a gl::Gl) -> Box<Component<'a>> + Send + 'static {
self.component_registrations.lock().unwrap().push(Box::new(register));
}
}
error[E0277]: the trait bound `for<'b> F: std::ops::Fn<(&'b ComponentRegistry<'b>, &'b gl::Gl)>` is not satisfied
--> src/main.rs:27:59
|
27 | self.component_registrations.lock().unwrap().push(Box::new(register));
| ^^^^^^^^^^^^^^^^^^ the trait `for<'b> std::ops::Fn<(&'b ComponentRegistry<'b>, &'b gl::Gl)>` is not implemented for `F`
|
= help: consider adding a `where for<'b> F: std::ops::Fn<(&'b ComponentRegistry<'b>, &'b gl::Gl)>` bound
= note: required for the cast to the object type `for<'b> std::ops::Fn(&'b ComponentRegistry<'b>, &'b gl::Gl) -> std::boxed::Box<Component<'b>> + std::marker::Send`

error[E0271]: type mismatch resolving `for<'b> <F as std::ops::FnOnce<(&'b ComponentRegistry<'b>, &'b gl::Gl)>>::Output == std::boxed::Box<Component<'b>>`
--> src/main.rs:27:59
|
27 | self.component_registrations.lock().unwrap().push(Box::new(register));
| ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'b, found concrete lifetime
|
note: concrete lifetime that was found is the lifetime 'a as defined on the method body at 26:5
--> src/main.rs:26:5
|
26 | / pub fn register_component<'a, F>(&mut self, register: F) where F: Fn(&'a ComponentRegistry<'a>, &'a gl::Gl) -> Box<Component<'a>> + Send + 'static {
27 | | self.component_registrations.lock().unwrap().push(Box::new(register));
28 | | }
| |_____^
= note: required for the cast to the object type `for<'b> std::ops::Fn(&'b ComponentRegistry<'b>, &'b gl::Gl) -> std::boxed::Box<Component<'b>> + std::marker::Send`

最佳答案

如果您在定义 component_registrations 时使用更高排名的生命周期struct 字段,您应该为 F 使用更高排名的生命周期

另外,如果你说 Box<Component<'b>> , 这真的意味着 Box<Component<'b> + 'static> (因此特征对象只能包含拥有的数据)。你真正需要的是 Box<Component<'b> + 'b> ,这意味着它是一个实现了 Component<'b> 的特征对象它还可以包含至少与 'b 一样长的借用数据。 .

相关部分是

pub struct Application {
component_registrations: Vec<Box<for<'b> Fn(&'b ComponentRegistry<'b>, &'b gl::Gl) -> Box<Component<'b> + 'b> + Send + 'static>>
}

impl Application {
pub fn register_component<F>(&mut self, register: F) where F: for<'b> Fn(&'b ComponentRegistry<'b>, &'b gl::Gl) -> Box<Component<'b> + 'b> + Send + 'static {
self.component_registrations.push(Box::new(register));
}
}

你可以看到 full example .请注意,我删除了 ArcMutex您示例中的类型,因为它们不相关。

关于rust - 在结构中存储具有生命周期的闭包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45482957/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com