为什么这个特征/实现不兼容 - 绑定生命周期与具体生命周期

时间:2015-06-21 03:22:05

标签: rust traits lifetime

我正在努力解决这个错误rustc给了我:

error: method `create_shader_explicit` has an incompatible type for trait: expected bound lifetime parameter 'a, found concrete lifetime

我的特质声明就是这样:

pub trait GraphicsContext<R: Resources> {

    /// Creates a shader object
    fn create_shader<'a>(&'a self, shader::Stage, source: &str) -> 
        Result<handle::Shader<R>, shader::CreateError>;

}

这是我的实施,

pub struct OpenGLResources<'a> {
    phantom: PhantomData<&'a u32> 
}

impl<'a> Resources for OpenGLResources<'a> {
    type Shader = Shader<'a>;
}

impl<'z> GraphicsContext<OpenGLResources<'z>> for OpenGLGraphicsContext {

    /// Creates a shader object
    fn create_shader<'a>(&'a self, stage: shader::Stage, source: &str) -> 
        Result<handle::Shader<OpenGLResources>, shader::CreateError> {

        let shader = Shader::new(self, stage);
        try!(shader.compile_from_source(source));

        Ok(shader)
    }

}

在StackOverflow上的other questions中,他们在<'a>create_shader之间缺少()之类的内容,但是当我比较我的fn定义时,它们看起来完全相同。

修改

impl内的定义更改为以下修复

fn create_shader<'a>(&'a self, stage: shader::Stage, source: &str) ->     
    Result<handle::Shader<OpenGLResources**<'z>**>, shader::CreateError>

但问题是'a'z必须是相同的生命周期。如果我改成它:

fn create_shader(**&'z** self, stage: shader::Stage, source: &str) -> 
    Result<handle::Shader<OpenGLResources<'z>>, shader::CreateError>

impl块有效,但我需要一种在特征定义中指定'z生命周期的方法。我尝试了以下方法:

pub trait<'z> GraphicsContext<R: Resources<'z>>

但它没有用。

2 个答案:

答案 0 :(得分:1)

在比较这样的事情时,您需要记住扩展所有泛型,以便实际比较所有这些。在这种情况下,您尚未展开R。如果您这样做,答案就变得明显了:ROpenGLResources<'z>,将OpenGLResourcesimpl块相关联,而您的方法定义已将OpenGLResources的生命周期排除在外},导致它被推断为self的生命周期,即'a

答案 1 :(得分:0)

感谢@Chris Morgan的提示我设法实现了这个功能,现在工作正常。

如果我们从包含'a生命周期的基本特征开始:

trait Resources<'a> {
    type Shader: Shader;
    type ShaderProgram: ShaderProgram;
}

然后为OpenGL实现它。 (注意PhantomData结构)

struct OpenGLResources<'a> {
   phantom: PhantomData<&'a u32> // 'a is the lifetime of the context reference
}

impl<'a> ResourcesTrait<'a> for Resources<'a> {
    type Shader = Shader<'a>;
    type ShaderProgram = ShaderProgram<'a>;
    type CommandBuffer = CommandBuffer;
    type CommandBufferBuilder = CommandBufferBuilder;
} 

它有点冗长,但GraphicsContext特性现在也可以正常工作。 'a生命周期在类型参数部分中。

trait GraphicsContext<'a, R: Resources<'a>> {

    fn create_shader(&'a self, ty: Type, source: &str) -> Result<R::Shader, ShaderCreationError>

}

最后,这是图形上下文实现中的必需代码。 'a生命周期到处都是极其冗长,但至少它有效!

impl<'a> GraphicsContext<'a, Resources<'a>> for OpenGLGraphicsContext