为什么这 trait/implementation 不兼容 - 绑定生命周期与具体生命周期

Why is this trait/implementation incompatible - bound lifetime vs concrete 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)
    }

}

在 Whosebug 的 other questions 中,它们在 create_shader() 之间缺少类似 <'a> 的东西,但是当我比较我的 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>>

但是没有用。

当比较这样的东西时,你需要记住展开所有泛型,这样你就可以真正比较它。在这种情况下,您还没有展开 R。如果这样做,答案就很明显了:ROpenGLResources<'z>,将 OpenGLResources 链接到 impl 块,而您的方法定义已经删除了 OpenGLResources 上的生命周期], 导致它被推断为 self 的生命周期,即 'a.

感谢@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