在 Rust 中,如何在不相互引用的情况下将两个对象的生命周期明确绑定在一起?

Jam*_*org 4 opengl reference lifetime rust

我遇到这种情况的具体情况是使用 OpenGL,struct为 aVertexBufferVertexArray. 本质上,每个结构体都是一个GLuint指向 OpenGL 对象的单个结构体。在最简单的情况下, aVertexArray恰好有一个VertexBuffer与之关联。

问题是VertexArray不能比其关联的VertexBuffer. Rust 不知道这一点,因为VertexArray持有的引用是 OpenGL 内部的,所以VertexBuffer在现有VertexArray引用它时调用析构函数没有问题。

我目前的解决方案是手动放置一个引用,该引用未使用:

struct VertexArray<'a> {
    id: GLuint,
    #[warn(dead_code)]
    vbo: &'a VertexBuffer
}
Run Code Online (Sandbox Code Playgroud)

在更复杂的情况下,引用可能是必要的,但感觉不优雅和浪费。可以使用引用数组/向量来实现具有多个 VBO 的 VAO。能够在创建 VAO 之后更改关联的缓冲区也可能会增加此要求。

有没有办法在没有参考的情况下实现相同的行为?或者,既然编译器可以识别出该引用从未被使用并给出警告,那么它会被优化掉吗?

Chr*_*gan 5

这是该PhantomData类型的主要用例之一,如示例中所示

应用于这种情况,你最终会得到这样的结果:

use std::marker::PhantomData;

struct VertexArray<'a> {
    id: GLuint,
    vbo_lifetime: PhantomData<&'a VertexBuffer>,
}
Run Code Online (Sandbox Code Playgroud)

实例化将是这样的:

    fn make<'a>(&'a self) -> VertexArray<'a> {
        VertexArray {
            id: …,
            vbo_lifetime: PhantomData,
        }
    }
Run Code Online (Sandbox Code Playgroud)

(这是省略了泛型类型,允许推断它;你也可以写PhantomData::<&'a VertexBuffer>.)