使用结构实现中的特征方法

时间:2017-09-04 00:19:19

标签: rust

我想像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实现中实现读或写。我希望将它们放在另一个文件中,因为它们将定义内存映射。我觉得这是一个简单的问题,我无法找到适合我的答案。

2 个答案:

答案 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的模块不必公开)。如果实现是在定义BusCPU的模块下的子模块中进行的,则子模块将自动访问这两种类型。否则,您需要在其中一个或两个声明中添加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!