我遇到这个问题的具体情况是使用 OpenGL,为 VertexBuffer
和 VertexArray
编写 struct
。从本质上讲,每个结构都是一个引用 OpenGL 对象的 GLuint
。在最简单的情况下,VertexArray
恰好有一个 VertexBuffer
与之关联。
问题是 VertexArray
不能比其关联的 VertexBuffer
存在时间更长。 Rust 并不知道这一点,因为 VertexArray
持有的引用是 OpenGL 内部的,所以在 VertexBuffer
上调用析构函数不会有问题,而现有的 VertexArray
引用它。
我目前的解决方案是手动添加一个未使用的引用:
struct VertexArray<'a> {
id: GLuint,
#[warn(dead_code)]
vbo: &'a VertexBuffer
}
在更复杂的情况下,引用可能被证明是必要的,但感觉不雅且浪费。具有多个 VBO 的 VAO 可以使用引用数组/向量来实现。能够在创建 VAO 之后更改关联的缓冲区也可能会增加此要求。
有没有办法在没有引用的情况下实现同样的行为?或者,既然编译器可以识别出引用从未被使用并发出警告,那么它会被优化掉吗?
最佳答案
这是 PhantomData
type 的主要用例之一, 作为 demonstrated there in an example .
应用于这种情况,你最终会得到这样的结果:
use std::marker::PhantomData;
struct VertexArray<'a> {
id: GLuint,
vbo_lifetime: PhantomData<&'a VertexBuffer>,
}
实例化将是这样的:
fn make<'a>(&'a self) -> VertexArray<'a> {
VertexArray {
id: …,
vbo_lifetime: PhantomData,
}
}
(这省略了通用类型,允许推断它;您也可以编写 PhantomData::<&'a VertexBuffer>
。)
关于opengl - 在 Rust 中,你如何明确地将两个对象的生命周期联系在一起,而不相互引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27219258/