2015-09-13 17 views
12

Sto tentando di memorizzare le trame del pistone in una struttura.Errore "parametro tipo previsto" nel costruttore di una struttura generica

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

Questo non può essere compilato:

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::Resourcesimplements gfx::Resources se (credo che sia solo l'implementazione specifica dispositivo.) Io in realtà non importa di che tipo si tratta, ma ho bisogno di sapere in modo che posso conservarlo nella struttura.

Ho fatto un compilable repo on Github.

(ho il sospetto Rust generics/traits: "expected 'Foo<B>', found 'Foo<Foo2>'" è la stessa domanda, ma non riesco a capire come applicarlo al mio problema.)

+0

Possibile duplicato di http://stackoverflow.com/questions/31490913/rust-generics-expected-t-found-foo o http://stackoverflow.com/questions/31060851/generics-error-expected-type- parameter-found-struct – Shepmaster

+0

Puoi usare [oggetti tratti] (http://doc.rust-lang.org/book/trait-objects.html), per ottenere il tipo di polimorfismo che il tuo codice sembra implicare. – cheme

risposta

18

Ecco una riproduzione del vostro errore:

struct Foo<T> { 
    val: T, 
} 

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

fn main() { 

} 

Il problema sorge perché hai provato a mentire al compilatore. Questo codice:

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

Says "Per una qualche T il chiamante sceglie, creerò un Foo con quel tipo". Quindi l'implementazione effettiva preleva un tipo di calcestruzzo - nell'esempio, un bool. Non è possibile garantire che T sia un bool. La funzione new non accetta nemmeno alcun parametro di tipo T, il che è altamente sospetto in quanto è così che il chiamante sceglie il tipo di calcestruzzo il 99% delle volte.

la correttezza modo di dire questo sarebbe

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

Anche se probabilmente si desidera scegliere un nome più specifico di new, come sembra come se si sta cercando di rendere il vostro struct generico. Presumibilmente ci sarebbero altri costruttori con tipi diversi.

per il codice esatto, probabilmente vuole qualcosa come

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

Naturalmente, un'altra possibile soluzione potrebbe essere quella di rimuovere il parametro di tipo generico dal vostro struct. Se lo costruisci solo con un gfx_device_gl::Resources, non c'è motivo di renderlo generico.

+0

grazie! Non mi ero reso conto che avrei potuto "specializzare" le cose in "impl". –

Problemi correlati