我想像Rust一样使用Rust中的特性。
struct CPU {
r: u32,
pc: u32
}
trait Bus {
fn read(&self, address: u32) -> u32;
fn write(&self, address: u32, data: u32) -> u32;
}
impl CPU {
fn step() {
let opcode = self.read(0xffff); // use Bus trait method here
}
}
我需要知道如何在我的CPU实现中使用特征方法,而不在CPU实现中实现读或写。我希望将它们放在另一个文件中,因为它们将定义内存映射。我觉得这是一个简单的问题,我无法找到适合我的答案。
答案 0 :(得分:2)
特质实施始终在他们自己的impl
区块中。
impl Bus for CPU {
fn read(&self, address: u32) -> u32 { unimplemented!() }
fn write(&self, address: u32, data: u32) -> u32 { unimplemented!() }
}
一个鲜为人知的诀窍是impl
块可以写在包中的任何模块中,只要该特征和类型都对该模块可见(包含impl
的模块不必公开)。如果实现是在定义Bus
和CPU
的模块下的子模块中进行的,则子模块将自动访问这两种类型。否则,您需要在其中一个或两个声明中添加pub(crate)
(或其他适合您的pub
形式)。当然,您可能需要use
特征和类型将它们放在包含impl
的模块的范围内,或者使用合格的路径。
例如,如果要将impl
放在子模块中,可以编写:
use super::Bus;
use super::CPU;
impl Bus for CPU {
fn read(&self, address: u32) -> u32 { unimplemented!() }
fn write(&self, address: u32, data: u32) -> u32 { unimplemented!() }
}
或
impl super::Bus for super::CPU {
fn read(&self, address: u32) -> u32 { unimplemented!() }
fn write(&self, address: u32, data: u32) -> u32 { unimplemented!() }
}
答案 1 :(得分:0)
好的,这就是我想要做的事情。
// bus controls reads and writes to/from emulated cpu
// a trait allows me to define the interface the cpu expects
pub trait Bus {
fn read(&self, size: Size, address: u32) -> u32;
fn write(&self, size: Size, address: u32, data: u32);
}
// must have an object to implement the bus on
pub struct Mem {} // this can be filled out later
// implement Bus trait for our Mem
impl Bus for Mem {
fn read(&self, size: Size, address: u32) -> u32 { unimplemented!() }
fn write(&self, size: Size, address: u32, data: u32) { unimplemented!() }
}
// here is our cpu struct with a generic Bus trait object in it
pub struct M68K<A: Bus> {
pub d: [u32; 8],
pub a: [u32; 8],
pub x: bool, // extend
pub n: bool, // negative
pub z: bool, // zero
pub v: bool, // overflow
pub c: bool, // carry
pub bus: A // here is the Bus trait object
}
// when we implement our cpu we can use the Bus trait methods, this allows
// multiple cpu's to be created with the same or different Bus objects.
// possibly connect 2 cpu's to the same Bus object?
impl M68K<Mem> {
pub fn step(&self, cycles: u32) {
let x = self.bus.read(Size::Byte, 0xffff);
}
}
此代码尚未完成。我的主要目标是为我自己的项目创建一个易于使用的68k cpu模拟器。在这里,我将所有内容都显示在一个文件中,但实际上现在可以编写整个cpu模拟器,而不需要了解我们实现的总线。我希望这是有道理的,它对我有用,我再次享受Rust!