通用结构的构造函数中的"预期类型参数"错误

Xav*_*hay 19 generics traits rust

我试图将活塞纹理存储在结构中.

struct TextureFactory<R> where R: gfx::Resources {
    block_textures: Vec<Rc<Texture<R>>>,
}

impl<R> TextureFactory<R> where R: gfx::Resources  {
    fn new(window: PistonWindow) -> Self {
        let texture = Rc::new(gfx_texture::Texture::from_path(
            &mut *window.factory.borrow_mut(),
            "assets/element_red_square.png",
            Flip::None, &TextureSettings::new()
        ).unwrap());
        let block_textures = Vec::new();
        block_textures.push(texture);

        TextureFactory {
            block_textures: block_textures,
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这不编译:

src/main.rs:37:9: 39:10 error: mismatched types:
 expected `TextureFactory<R>`,
    found `TextureFactory<gfx_device_gl::Resources>`
(expected type parameter,
    found enum `gfx_device_gl::Resources`)
Run Code Online (Sandbox Code Playgroud)

gfx_device_gl::Resources gfx::Resources虽然实现(我认为它只是设备特定的实现.)我实际上并不关心这是什么类型,但我需要知道,以便我可以将它存储在结构中.

在Github做了一个可编辑的回购.

(我怀疑Rust的特征/特征:"预期'Foo <B>',发现'Foo <Foo2>'"是同一个问题,但我无法弄清楚如何将它应用到我的问题中.)

She*_*ter 29

这是你的错误的再现:

struct Foo<T> {
    val: T,
}

impl<T> Foo<T> {
    fn new() -> Self {
        Foo { val: true }
    }
}

fn main() {}
Run Code Online (Sandbox Code Playgroud)

问题出现是因为你试图欺骗编译器.这段代码:

impl<T> Foo<T> {
    fn new() -> Self {
        /* ... */
    }
}
Run Code Online (Sandbox Code Playgroud)

说"无论T打电话者选择什么,我都会创建一个Foo类型".然后你的实际实现选择一个具体的类型 - 在例子中,a bool.不能保证T是一个bool.请注意,您的new函数甚至不接受任何类型的参数T,这是非常可疑的,因为这是调用者99%的时间选择具体类型的方式.

这样说的正确方法是

impl Foo<bool> {
    fn new() -> Self {
        Foo { val: true }
    }
}
Run Code Online (Sandbox Code Playgroud)

虽然您可能希望选择一个更具体的名称new,因为它看起来好像您正在尝试使您的结构通用.据推测,会有其他不同类型的构造函数.

对于您的确切代码,您可能需要类似的东西

impl TextureFactory<gfx_device_gl::Resources> { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

当然,另一种可能的解决方案是从结构中删除泛型类型参数.如果你只用a构造它gfx_device_gl::Resources,那么就没有理由把它变成通用的.