English 中文(简体)
缩略语
原标题:Abstracting mutable/immutable references in rust

我需要消除本法典中的重复:

pub struct Memory {
    layout: MemoryLayout,
    rom: Vec<u8>,
    ram: Vec<u8>,
}

impl Memory {
    pub fn get_mem_vec_ref(&self, address: u32) -> Result<&Vec<u8>, RiscvError> {
        // ...

        let mem_vec_ref = match address {
            addr if (rom_start..rom_end).contains(&addr) => Ok(&self.rom),
            addr if (ram_start..ram_end).contains(&addr) => Ok(&self.ram),
            addr => Err(RiscvError::MemoryAlignmentError(addr)),
        }?;

        return Ok(mem_vec_ref);
    }

    pub fn get_mem_vec_mut_ref(&mut self, address: u32) -> Result<&mut Vec<u8>, RiscvError> {
        // ...

        let mem_vec_ref = match address {
            addr if (rom_start..rom_end).contains(&addr) => Ok(&mut self.rom),
            addr if (ram_start..ram_end).contains(&addr) => Ok(&mut self.ram),
            addr => Err(RiscvError::MemoryAlignmentError(addr)),
        }?;

        return Ok(mem_vec_ref);
    }
}

How can I abstract using mutable vs immutable reference to self? Can Box or RefCell be helpful in this case?

问题回答

由于你重新处理这两个案件的参考文献,你可以界定一个通用功能,即<代码>T>和>;Vec<u8>或&mut Vec<u8>。 因此,你可以做这样的事情:

fn get_mem<T>(address: u32, rom: T, ram: T) -> Result<T, RiscvError> {
    // ...

    match address {
        addr if (rom_start..rom_end).contains(&addr) => Ok(rom),
        addr if (ram_start..ram_end).contains(&addr) => Ok(ram),
        addr => Err(RiscvError::MemoryAlignmentError(addr)),
    }
}

impl Memory {
    pub fn get_mem_vec_ref(&self, address: u32) -> Result<&Vec<u8>, RiscvError> {
        // ...

        let mem_vec_ref = get_mem(address, &self.rom, &self.ram)?;

        return Ok(mem_vec_ref);
    }

    pub fn get_mem_vec_mut_ref(&mut self, address: u32) -> Result<&mut Vec<u8>, RiscvError> {
        // ...

        let mem_vec_ref = get_mem(address, &mut self.rom, &mut self.ram)?;

        return Ok(mem_vec_ref);
    }
}

现在,显然需要修改<代码>get_mem(,以核算rom_start,rom_end,ram_start,ram_end。 如果你想避免将100个田地通过get_mem(>”,那么,也许应该采用一种新的类型来处理地址,例如:

struct Addr {
    // ...
}

impl Addr {
    fn get_mem<T>(&self, rom: T, ram: T) -> Result<T, RiscvError> {
        // ...
    }
}




相关问题
Good reference site for SQL/RDBMS

One of the aspects of computer science/practical software engineering I am weaker at is actually doing significant work in database systems. That is to say, I can do simple queries on smaller datasets,...

Reference two equal assemblies, only public keys differ

My Visual Studio 2008 project references two (external) assemblies (A+B) both of which happen to be referencing the same third assembly (C). However, assembly A expects assembly C to have a public key ...

Size of reference of an class in JAVA

What is the size of reference of a class in Java? Is it constant for a particular JVM and OS irrespective of the class for which the reference is made. Class A Class B Class C A a; B b; C c; Are ...

Should I use a const reference or a boost::shared_ptr?

I have created some C++ classes to model a Solitaire game as a learning exercise. I have classes for the SolitaireGame, a CardStack (one of the 10 piles of cards on the board ) and a Card. My ...

Data Destruction In C++

So, for class I m (constantly re-inventing the wheel) writing a bunch of standard data structures, like Linked Lists and Maps. I ve got everything working fine, sort of. Insertion and removal of ...

Implementing the ICloneable Interface C# (Deep Cloning)

I was looking at code that implemented the ICloneable interface for one of the classes. The class was as follows: public class TempClass { String[] names; String[] values; } A partial class was ...

热门标签