最近一周,我因为生命周期的问题而苦恼不已。
当我尝试在DataSource
中引用Buffer
的引用,并将其引用到DrawCommand
中时,就会出现问题。我收到了这个错误:vertex_data_source
没有足够长的生命周期。
src/main.rs:65:23: 65:41 error:
src/main.rs:65 data_source: &vertex_data_source
^~~~~~~~~~~~~~~~~~
src/main.rs:60:51: 67:2 note: reference must be valid for the block suffix following statement 3 at 60:50...
src/main.rs:60 let vertices = VertexAttributes::new(&buffer);
src/main.rs:61
src/main.rs:62 let vertex_data_source = factory.create_data_source(vertices);
src/main.rs:63
src/main.rs:64 let command: DrawCommand<ResourcesImpl> = DrawCommand {
src/main.rs:65 data_source: &vertex_data_source
...
src/main.rs:62:67: 67:2 note: ...but borrowed value is only valid for the block suffix following statement 4 at 62:66
src/main.rs:62 let vertex_data_source = factory.create_data_source(vertices);
src/main.rs:63
src/main.rs:64 let command: DrawCommand<ResourcesImpl> = DrawCommand {
src/main.rs:65 data_source: &vertex_data_source
src/main.rs:66 };
src/main.rs:67 }
它说
vertex_data_source
必须在第60行后的块后缀语句中有效。我对这个错误的解释是,vertex_data_source
应该在第60行之前被定义。但是,要首先创建vertex_data_source
,我需要访问第60行上的那些VertexAttributes
,所以我不能只是交换顺序。我觉得我的代码中所有分散的'a生命周期需要拆分成2个或者只是删除,然而我尝试了每一个看起来合理的组合,但是我没有新的想法。
下面是一个大大简化了的示例代码,它演示了问题。我真的很感激您的帮助和建议,希望您能发现问题。(每次在几天的折腾之前都会产生一个修复,但这一次我卡住了)。
use std::cell::RefCell;
use std::marker::PhantomData;
pub struct DrawCommand<'a, R: Resources<'a>> {
pub data_source: &'a R::DataSource
}
pub trait Resources<'a> {
type DataSource: 'a;
type Buffer: 'a;
}
pub struct DataSource<'a> {
id: u32,
attributes: Vec<VertexAttributes<'a, ResourcesImpl<'a>>>,
current_element_array_buffer_binding: RefCell<Option<Buffer<'a>>>
}
pub struct Buffer<'a> {
context: &'a GraphicsContextImpl
}
pub struct GraphicsContextImpl;
pub struct ResourcesImpl<'a> {
phantom: PhantomData<&'a u32> // 'a is the lifetime of the context reference
}
impl<'a> Resources<'a> for ResourcesImpl<'a> {
type Buffer = Buffer<'a>;
type DataSource = DataSource<'a>;
}
struct Factory<'a> {
context: &'a GraphicsContextImpl
}
impl<'a> Factory<'a> {
/// Creates a buffer
fn create_buffer<T>(&self) -> Buffer<'a> {
Buffer {
context: self.context
}
}
fn create_data_source(&self, attributes: Vec<VertexAttributes<'a, ResourcesImpl<'a>>>) -> DataSource<'a> {
DataSource {
id: 0,
attributes: attributes,
current_element_array_buffer_binding: RefCell::new(None)
}
}
}
fn main() {
let context = GraphicsContextImpl;
let factory = Factory {
context: &context
};
let buffer = factory.create_buffer::<u32>();
let vertices = VertexAttributes::new(&buffer);
let vertex_data_source = factory.create_data_source(vec!(vertices));
let command: DrawCommand<ResourcesImpl> = DrawCommand {
data_source: &vertex_data_source
};
}
pub struct VertexAttributes<'a, R: Resources<'a>> {
pub buffer: &'a R::Buffer,
}
impl<'a, R: Resources<'a>> VertexAttributes<'a, R> {
pub fn new(buffer: &'a R::Buffer) -> VertexAttributes<'a, R> {
VertexAttributes {
buffer: buffer
}
}
}
非常感谢你提前的帮助。
编辑:
我已经更新了代码,以更好地反映我的实际实现。
顺便说一句 - 替换这个:
let vertex_data_source = factory.create_data_source(vec!(vertices));
有了这个:
let vertex_data_source = DataSource {
id: 0,
attributes: vec!(vertices),
current_element_array_buffer_binding: RefCell::new(None)
};
无法解决该问题。
attributes
被传递给create_data_source
却从未被使用?为什么create_data_source
是Factory
的一个方法,却从未引用过它?为什么在该方法中使用'a
,却与该生命周期没有任何关系?我可以告诉你为什么会出现错误,但如果不清楚你在做什么,我无法开始建议如何修复它... - DK.attributes
)。create_data_source
是一个工厂中的方法,因为在我的实际实现中将有许多不同的工厂(OpenGL工厂、DirectX工厂等)。然而,即使我只是在工厂之外创建vertex_data_source
,问题仍然存在,所以我认为真正的问题在于DataSource
结构体本身的生命周期。 - neon64