2017-09-04 21 views
1

我想在界面中使用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

这是**高度建议**,你阅读**优秀** [*锈编程语言*](https://doc.rust-lang.org/stable/book/second-edition/)其中涵盖了很多这些介绍性问题。这在[特性章节](https://doc.rust-lang.org/stable/book/second-edition/ch10-02-traits.html)中有介绍。 – Shepmaster

+0

我读过这本书的第一版,没有意识到有第二版,我必须阅读它,因为Rust自从我上次使用它之后发生了一些变化。我想我的主要问题是从基于继承的语言切换到Rust的基于合成的设计。 –

回答

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!() } 
} 
+0

谢谢!我从鲁斯特休息一下,并且遇到了麻烦。这工作完美。 –

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模拟器现在可以在没有任何有关总线实现的知识的情况下编写。我希望这是有道理的,它对我有用,我再次享受着鲁斯特!

相关问题