Ich bin unglaublich neu in dem Versuch, Generika zu schreiben, und Rust's Eigenschaften entziehen sich meinem Verständnis. Ich habe dieses Stück Code bekam:Probleme beim Verstehen von Merkmalen und Generika in Rust
pub trait Mapper {
fn prg_rom_read(&self, addr: u16) -> u8 {}
fn prg_rom_write(&mut self, addr: u16, val: u8) {}
fn chr_rom_read(&self, addr: u16) -> u8 {}
fn chr_rom_write(&mut self, addr: u16, val: u8) {}
}
pub fn choose_mapper<M: Mapper>(rom_header: &RomHeader) -> M {
match rom_header.mapper_number {
0 => Mapper1::new(rom_header),
_ => panic!("Unsupported mapper: {:#}", rom_header.mapper_number),
}
}
struct Mapper1 {
prg_ram: Box<[u8]>,
prg_rom: Box<[u8]>,
chr: Box<[u8]>,
}
impl Mapper1 {
pub fn new(rom_header: &RomHeader) -> Self {
Mapper1 {
prg_ram: {
let size = rom_header.prg_ram_size as usize * 8192;
vec![0; size].into_boxed_slice()
},
prg_rom: {
let size = rom_header.prg_rom_size as usize * 16384;
vec![0; size].into_boxed_slice()
},
chr: {
let size = rom_header.chr_rom_size as usize * 8192;
vec![0; size].into_boxed_slice()
},
}
}
}
impl Mapper for Mapper1 {
fn prg_rom_read(&self, addr: u16) -> u8 {}
fn prg_rom_write(&mut self, addr: u16, val: u8) {}
fn chr_rom_read(&self, addr: u16) -> u8 {}
fn chr_rom_write(&mut self, addr: u16, val: u8) {}
}
, in dem ich versuche, ein Merkmal zu definieren, impl dieses Merkmal auf mehrere structs, dann eine Funktion haben, die eine dieser structs zurückgibt. Ist das überhaupt möglich?
Ich erhalte die Compiler-Fehler:
expected `_`,
found `mapper::Mapper1`
(expected type parameter,
found struct `mapper::Mapper1`) [E0308]
src/mapper.rs:11 match rom_header.mapper_number {
src/mapper.rs:12 0 => Mapper1::new(rom_header),
src/mapper.rs:13 _ => panic!("Unsupported mapper: {:#}", rom_header.mapper_number),
src/mapper.rs:14 }
src/mapper.rs:11:5: 14:6 help: run `rustc --explain E0308` to see a detailed explanation
src/mapper.rs:12:14: 12:38 note: match arm with an incompatible type
src/mapper.rs:12 0 => Mapper1::new(rom_header),
^~~~~~~~~~~~~~~~~~~~~~~~
Das macht Sinn. Soll ich dann Box :: new() in den Match-Armen von Mapper auswählen? oder sollte jeder neue() eine Box zurückgeben? Wenn ich das tue, dann wenn ich versuche, dies in einem anderen Modul zu tun: –
cafeclimber
Also klar, ich muss Box :: new() verwenden, wenn ich versuche, choose_mapper von einem anderen Modul aufzurufen und das Ergebnis entweder a zuweisen Variable oder Feld struct, bekomme ich diesen Fehler: nicht in der Lage, genug Typ Informationen über '_'; Typ Anmerkungen oder generische Parameterbindung erforderlich. Ich habe versucht, Casting und geben Sie die Spezifikation ohne Erfolg ... – cafeclimber
Haben Sie '' entfernen? Wenn Sie eine Box zurückgeben, ist die Funktion nicht mehr generisch. –
mcarton