由于生命中这个令人难以置信的恼人问题,我上周一直在拔头发。
当我尝试在tickValues([0,1])
中引用Buffer
时引发问题,然后将其引用到DataSource
。我收到了错误消息: 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 }
必须对第60行语句3后面的块后缀有效。我对该错误的解释是 vertex_data_source
应该在第60行之前定义。但是要首先创建vertex_data_source
我需要在第60行访问那些vertex_data_source
,所以我不能只是交换订单。
我觉得我的代码上的所有'a 生命周期都需要分成2个或者可能只是删除了,但是我尝试了所有看起来合理的组合并且我没有离开想法。
以下是我的代码的一个非常简化的示例,用于演示此问题。我非常感谢理智检查,希望新思维能够发现问题。 (每次摆弄几天之前都会产生修复,但这次我很难过。)
VertexAttributes
非常感谢。
修改
我已更新代码以更好地反映我的实际实施情况。
顺便说一句 - 替换这个:
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));
无法解决问题。
答案 0 :(得分:0)
这允许您的示例编译:
pub struct DrawCommand<'a : 'b, 'b, R: Resources<'a>> {
pub data_source: &'b R::DataSource
}
但是,我发现创建一个更小的例子非常困难。我可以确定,您有一个问题,因为您声明您将持有对自身具有引用的项的引用,并且这两个引用需要具有共同的生命周期('a
)。通过其他生命周期的某种组合,这实际上是不可能的。
添加第二个生命周期允许引用 DataSource
与DataSource
本身的引用不同。
我仍然会尝试创建一个更小的例子。