generics - 泛型结构的构造函数中出现 "Expected type parameter"错误

标签 generics rust traits

我正在尝试将 Piston 纹理存储在结构中。

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,
        }
    }
}

这不编译:

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`)

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

我做了一个compilable repo on Github .

(我怀疑 Rust generics/traits: "expected 'Foo<B>', found 'Foo<Foo2>'" 是同一个问题,但我不知道如何将它应用于我的问题。)

最佳答案

这是您的错误的重现:

struct Foo<T> {
    val: T,
}

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

fn main() {}

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

impl<T> Foo<T> {
    fn new() -> Self {
        /* ... */
    }
}

说“对于调用者选择的任何T,我都将创建一个具有该类型的Foo”。然后您的实际实现选择一个具体类型 — 在示例中,一个bool。无法保证 T 是一个 bool。请注意,您的 new 函数甚至不接受任何 T 类型的参数,这很值得怀疑,因为调用者在 99% 的情况下都是这样选择具体类型的。

正确的说法是

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

虽然您可能想选择一个比 new 更具体的名称,因为看起来您正试图使您的结构通用。大概会有不同类型的其他构造函数。

对于你的确切代码,你可能想要类似的东西

impl TextureFactory<gfx_device_gl::Resources> { /* ... */ }

另一种可能的解决方案是从您的结构中删除泛型类型参数。如果您只使用 gfx_device_gl::Resources 构建它,那么就没有理由将其设为通用。

在其他情况下,您可能会尝试返回实现特征的类型。为此,您可以使用盒装特征对象:

impl Foo<Box<dyn std::fmt::Display>> {
    fn new() -> Self {
        Foo { val: Box::new(true) }
    }
}

将来,您还可以使用 impl Trait(又名 existential types):

#![feature(type_alias_impl_trait)]

struct Foo<T> {
    val: T,
}

type SomeConcreteButOpaqueType = impl std::fmt::Display;

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

另见:

关于generics - 泛型结构的构造函数中出现 "Expected type parameter"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58810793/

相关文章:

rust - Rust 可以调用抽象函数吗?

c# - 在泛型方法中实例化 Wrapper 对象

swift - 创建一个通用的 Swift 函数来返回一个 Core Data 实体数组

java - 泛型类型推断不适用于方法链接?

asynchronous - 如何使用rlua-async执行异步lua代码?

scala - Scala的MapLike,ListLike,SeqLike等如何分别与Map,List,Seq进行比较?

c# - 简单的一般性误解

visual-studio-2015 - 为什么 Rust 代码补全在我的 Visual Studio 2015 中不起作用?

rust - 无法在 Rust/Actix 应用程序中使用柴油计时功能

php - 如何限制某些类的 PHP 特性