2017-09-04 66 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模擬器現在可以在沒有任何有關總線實現的知識的情況下編寫。我希望這是有道理的,它對我有用,我再次享受着魯斯特!

相關問題