[英]In Rust, how do you explicitly tie the lifetimes of two objects together, without referencing eachother?
The specific case where I ran into this was in using OpenGL, writing struct
s for a VertexBuffer
and VertexArray
. 我碰到的具体情况是使用OpenGL,为
VertexBuffer
和VertexArray
编写struct
。 Each struct is, in essence, a single GLuint
that refers to the OpenGL object. 实质上,每个结构都是一个引用OpenGL对象的
GLuint
。 In the simplest case, a VertexArray
has exactly one VertexBuffer
associated with it. 在最简单的情况下,
VertexArray
只有一个VertexBuffer
关联的VertexBuffer
。
The problem is that the VertexArray
cannot live longer than its associated VertexBuffer
. 问题是
VertexArray
寿命不能超过其关联的VertexBuffer
。 Rust doesn't know this though, since the reference that the VertexArray
holds is internal to OpenGL, so it will have no problem calling the destructor on the VertexBuffer
while an existing VertexArray
references it. 虽然Rust不知道这一点,因为
VertexArray
所持有的引用是OpenGL内部的,所以当现有的VertexArray
引用它时,调用VertexBuffer
上的析构函数是没有问题的。
The current solution I have is to put a reference in manually, which goes unused: 我当前的解决方案是手动放置一个引用,该引用未使用:
struct VertexArray<'a> {
id: GLuint,
#[warn(dead_code)]
vbo: &'a VertexBuffer
}
In more complex cases, the reference might turn out to be necessary, but it feels inelegant and wasteful. 在更复杂的情况下,参考可能证明是必要的,但它感觉不雅和浪费。 A VAO with multiple VBOs could be implemented with an array/vector of references.
具有多个VBO的VAO可以用引用的数组/向量来实现。 Being able to change the associated buffers after the VAO has been created might also add this requirement.
在创建VAO之后能够更改关联的缓冲区也可能会添加此要求。
Is there any way to achieve this same behaviour without the reference? 有没有办法在没有参考的情况下实现同样的行为? Or, since the compiler can recognize that the reference is never used and give a warning, will it be optimized out?
或者,由于编译器可以识别出从未使用过引用并发出警告,它是否会被优化掉?
This is one of the primary use cases for the PhantomData
type , as demonstrated there in an example . 这是
PhantomData
类型的主要用例之一,如示例中所示 。
Applied to this case, you'll end up with something like this: 应用于这种情况,你最终会得到这样的东西:
use std::marker::PhantomData;
struct VertexArray<'a> {
id: GLuint,
vbo_lifetime: PhantomData<&'a VertexBuffer>,
}
And instantiation will be something like this: 实例化将是这样的:
fn make<'a>(&'a self) -> VertexArray<'a> {
VertexArray {
id: …,
vbo_lifetime: PhantomData,
}
}
(This is eliding the generic type, allowing it to be inferred; you could also write PhantomData::<&'a VertexBuffer>
.) (这样可以省略泛型类型,允许它被推断;你也可以编写
PhantomData::<&'a VertexBuffer>
。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.