如何对不直接使用该类型的结构进行类型参数化?

How can I type parameterize a struct that doesn't use that type directly?

过去编译过此代码,但最近它不再被接受(我相信自 RFC 738 以来)。我想对 VertexBuffer 进行类型参数化,但它实际上并不包含任何顶点,而是 GPU 包含顶点,而该结构仅包含 OpenGL buffer_id:

pub struct VertexBuffer<V: Vertex> {
    buffer_id: GLuint,
    num_vertices: usize,
}

new函数填充缓冲区:

impl<V: Vertex> VertexBuffer<V> {
    pub fn new(data: &Vec<V>) -> VertexBuffer<V>
    {
        let buffer_id = unsafe {
            let mut id: GLuint = 0;
            gl::GenBuffers(1, &mut id);
            gl::BindBuffer(gl::ARRAY_BUFFER, id);
            gl::BufferData(gl::ARRAY_BUFFER,
                (mem::size_of::<V>() * data.len()) as GLsizeiptr,
                 mem::transmute(&data[0]),
                 gl::STATIC_DRAW);
            id
        };

        VertexBuffer {
            buffer_id: buffer_id,
            num_vertices: data.len(),
        }
    }
    ....
}

我现在收到这些错误:

src/vertex_buffer.rs:10:25: 10:26 error: parameter `V` is never used
src/vertex_buffer.rs:10 pub struct VertexBuffer<V: Vertex> {

src/vertex_buffer.rs:10:25: 10:26 help: consider removing `V` or using a marker such as `core::marker::PhantomData`
src/vertex_buffer.rs:10 pub struct VertexBuffer<V: Vertex> {

仅供参考,impl 中的其他函数,如 pre_render() 和 post_render() 使用 V 类型来完成它们的工作,调用诸如

let attribute_data = Vertex::attribute_data(None::<V>);

您没有显示足够的代码来排除这种情况,所以我建议将您的类型移至函数:

impl VertexBuffer {
    pub fn new<V: Vertex>(data: &Vec<V>) -> VertexBuffer<V> {
        let buffer_id = unsafe {
            let mut id: GLuint = 0;
            gl::GenBuffers(1, &mut id);
            gl::BindBuffer(gl::ARRAY_BUFFER, id);
            gl::BufferData(gl::ARRAY_BUFFER,
                (mem::size_of::<V>() * data.len()) as GLsizeiptr,
                 mem::transmute(&data[0]),
                 gl::STATIC_DRAW);
            id
        };

        VertexBuffer {
            buffer_id: buffer_id,
            num_vertices: data.len(),
        }
    }
    ....
}

如果您确实需要使用 PhantomData,请尝试以下方法:

struct VertexBuffer<V> {
    buffer_id: u32, // or whatever
    num_vertices: u32, // or whatever
    marker: std::marker::PhantomData<V>,
}

impl<V: Vertex> VertexBuffer<V> {
    pub fn new(data: &Vec<V>) -> VertexBuffer<V> {
        let buffer_id = unsafe {
            let mut id: GLuint = 0;
            gl::GenBuffers(1, &mut id);
            gl::BindBuffer(gl::ARRAY_BUFFER, id);
            gl::BufferData(gl::ARRAY_BUFFER,
                (mem::size_of::<V>() * data.len()) as GLsizeiptr,
                 mem::transmute(&data[0]),
                 gl::STATIC_DRAW);
            id
        };

        VertexBuffer {
            buffer_id: buffer_id,
            num_vertices: data.len(),
            marker: std::marker::PhantomData,
        }
    }
    ....
}