我正在使用Rust开发一款小型NES模拟器,并尝试在状态寄存器上添加新的特性。该寄存器是一个结构体,其中包含几个字段(标志位),每个字段都包含一个布尔值,而该寄存器本身是CPU结构体的一部分。
现在,我想循环遍历这些字段,并根据执行的某些指令设置布尔值。然而,我无法实现可变迭代器,我已经实现了into_iter()函数,并能够遍历这些字段以获取/打印布尔值,但如何在结构体本身内部改变这些值呢?这是可能的吗?
pub struct StatusRegister {
CarryFlag: bool,
ZeroFlag: bool,
OverflowFlag: bool,
}
impl StatusRegister {
fn new() -> Self {
StatusRegister {
CarryFlag: true,
ZeroFlag: false,
OverflowFlag: true,
}
}
}
impl<'a> IntoIterator for &'a StatusRegister {
type Item = bool;
type IntoIter = StatusRegisterIterator<'a>;
fn into_iter(self) -> Self::IntoIter {
StatusRegisterIterator {
status: self,
index: 0,
}
}
}
pub struct StatusRegisterIterator<'a> {
status: &'a StatusRegister,
index: usize,
}
impl<'a> Iterator for StatusRegisterIterator<'a> {
type Item = bool;
fn next(&mut self) -> Option<bool> {
let result = match self.index {
0 => self.status.CarryFlag,
1 => self.status.ZeroFlag,
2 => self.status.OverflowFlag,
_ => return None,
};
self.index += 1;
Some(result)
}
}
pub struct CPU {
pub memory: [u8; 0xffff],
pub status: StatusRegister,
}
impl CPU {
pub fn new() -> CPU {
let memory = [0; 0xFFFF];
CPU {
memory,
status: StatusRegister::new(),
}
}
fn execute(&mut self) {
let mut shifter = 0b1000_0000;
for status in self.status.into_iter() {
//mute status here!
println!("{}", status);
shifter <<= 1;
}
}
}
fn main() {
let mut cpu = CPU::new();
cpu.execute();
}
&mut
,这与&
有很大的区别,因为引用实现了复制,但可变引用不会。因此,编译器需要借用迭代器以确保可变引用仅被借用一次,但您无法这样做,因为 Rust 没有 GATs。我认为 std 在其可变迭代器实现中使用了不安全的方法。 - Stargateurslice::IterMut
没有什么不同(除了在安全代码中可以通过两种不同的方式解决它)。 - trentIterMut
在安全代码中实现起来很困难,但在类型系统中表达起来很容易。 - trent