"Expected type parameter" 泛型结构的构造函数出错
"Expected type parameter" error in the constructor of a generic struct
我正在尝试将活塞纹理存储在结构中。
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 {
/* ... */
}
}
说 "For whatever T
the caller chooses, I will create a Foo
with that type"。然后你的实际实现选择一个具体类型——在这个例子中,一个bool
。无法保证 T
是 bool
。请注意,您的 new
函数甚至不接受类型为 T
的任何参数,这是非常值得怀疑的,因为这就是调用者在 99% 的情况下选择具体类型的方式。
正确的说法是
impl Foo<bool> {
fn new() -> Self {
Foo { val: true }
}
}
虽然您可能想选择一个比 new
更具体的名称,因为看起来您正在尝试使您的结构通用。大概会有 other 个不同类型的构造函数。
对于您的确切代码,您可能需要类似
的东西
impl TextureFactory<gfx_device_gl::Resources> { /* ... */ }
另一种可能的解决方案是从结构中删除泛型类型参数。如果您只使用 gfx_device_gl::Resources
构建它,那么就没有理由将其设为通用。
在其他情况下,您可能会尝试 return 实现特征的类型。为此,您可以使用盒装特征对象:
impl Foo<Box<dyn std::fmt::Display>> {
fn new() -> Self {
Foo { val: Box::new(true) }
}
}
以后,您也许还可以使用impl Trait
(a.k.a。存在类型):
#![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 }
}
}
另请参阅:
- What is the correct way to return an Iterator (or any other trait)?
我正在尝试将活塞纹理存储在结构中。
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 {
/* ... */
}
}
说 "For whatever T
the caller chooses, I will create a Foo
with that type"。然后你的实际实现选择一个具体类型——在这个例子中,一个bool
。无法保证 T
是 bool
。请注意,您的 new
函数甚至不接受类型为 T
的任何参数,这是非常值得怀疑的,因为这就是调用者在 99% 的情况下选择具体类型的方式。
正确的说法是
impl Foo<bool> {
fn new() -> Self {
Foo { val: true }
}
}
虽然您可能想选择一个比 new
更具体的名称,因为看起来您正在尝试使您的结构通用。大概会有 other 个不同类型的构造函数。
对于您的确切代码,您可能需要类似
的东西impl TextureFactory<gfx_device_gl::Resources> { /* ... */ }
另一种可能的解决方案是从结构中删除泛型类型参数。如果您只使用 gfx_device_gl::Resources
构建它,那么就没有理由将其设为通用。
在其他情况下,您可能会尝试 return 实现特征的类型。为此,您可以使用盒装特征对象:
impl Foo<Box<dyn std::fmt::Display>> {
fn new() -> Self {
Foo { val: Box::new(true) }
}
}
以后,您也许还可以使用impl Trait
(a.k.a。存在类型):
#![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 }
}
}
另请参阅:
- What is the correct way to return an Iterator (or any other trait)?