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

时间:2014-11-30 22:55:36

标签: opengl reference rust lifetime

我遇到这种情况的具体情况是使用OpenGL,为structVertexBuffer编写VertexArray。实质上,每个结构都是一个引用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后更改关联的缓冲区也可能会增加此要求。

有没有办法在没有参考的情况下实现同样的行为?或者,由于编译器可以识别出从未使用过引用并发出警告,它是否会被优化掉?

1 个答案:

答案 0 :(得分:3)

这是ContravariantLifetime marker的用途。它的使用方式如下:

use std::kinds::marker::ContravariantLifetime;

struct VertexArray<'a> {
    id: GLuint,
    vbo_marker: ContravariantLifetime<'a>,
}

实例化:

fn make<'a>(&'a self) -> VertexArray<'a> {
    VertexArray {
        id: …,
        vbo_marker: ContravariantLifetime::<'a>,
    }
}

或(终身寿命):

fn make(&self) -> VertexArray {
    VertexArray {
        id: …,
        vbo_marker: ContravariantLifetime,
    }
}