存在该方法``fold` for for参考'& [t]`,但其特征界限不满足,我不了解所涉及的给定界限

发布于 2025-01-18 15:43:28 字数 3044 浏览 3 评论 0原文

因此,我正在构建一个CHIP-8 CPU仿真器,并使复制数据更容易地创建以下两个方法:

pub struct CPU {
    // ... other unrelated fields
    pub memory: [u8; 0x1000],
}

impl CPU {
    pub fn raw_copy_to_mem(&mut self, loc: usize, data: &[u8]) {
        data.chunks(2).fold(loc, |loc, bytes| {
            self.raw_add_to_mem(loc, *bytes.first().unwrap(), *bytes.last().unwrap())
        });
    }

    pub fn raw_add_to_mem(&mut self, loc: usize, high: u8, low: u8) -> usize {
        self.memory[loc] = high; self.memory[loc + 1] = low;
        loc + 2
    }
}

现在,这对此有效:

fn make_cpu() -> processor::CPU {

   processor::CPU {
        // ... other unrelated fields
        memory: [0; 0x1000],
    }
}
#[test]
fn test_raw_memory_copy() {
    let mut cpu = make_cpu();

    let add_twice: [u8; 6] = [
        0x80, 0x14,
        0x80, 0x14,
        0x00, 0xEE,
    ];

    cpu.raw_copy_to_mem(0x100 , &add_twice);

    assert_eq!(cpu.memory[0x100..0x106], add_twice);

}

现在,使执行操作码更容易,我具有以下结构和功能

#[derive(Debug, Clone, Copy)]
pub struct OpCode(u8, u8);

impl OpCode {
    pub fn high_byte(&self) -> u8 {
        self.0
    }

    pub fn low_byte(&self) -> u8 {
        self.1
    }
}

impl From<OpCode> for u16 {
    fn from(c: OpCode) -> Self {
        (c.0 as u16) << 8 | c.1 as u16
    }
}

impl From<&OpCode> for u16 {
    fn from(c: &OpCode) -> u16 {
        c.into()
    }
}

impl OpCode {
    pub fn add(h: u8, l: u8) -> Self {
        Self (0x8 << 4 | h, (l << 4) | 4)
    }
}

:以下CPU函数也很棒:

impl CPU {
    pub fn add_to_mem(&mut self, loc: usize, oc: &OpCode) -> usize {
        self.memory[loc] = oc.high_byte(); self.memory[loc + 1] = oc.low_byte();
        loc + 2
    }
}

当我尝试添加opCode struct的copy_to_mem()函数时,就会发生问题:

impl CPU {
    pub fn copy_to_mem(&mut self, loc: usize, data: &[OpCode]) {
        data.fold(loc, |loc, opcode| {
            self.add_to_mem(loc, opcode)
        });
    }
}

我只能理解的下列错误

error[E0599]: the method `fold` exists for reference `&[OpCode]`, but its trait bounds were not satisfied
  --> src/processor.rs:21:14
   |
21 |         data.fold(loc, |loc, bytes| {
   |              ^^^^ method cannot be called on `&[OpCode]` due to unsatisfied trait bounds
   |
   = note: the following trait bounds were not satisfied:
           `&[OpCode]: Iterator`
           which is required by `&mut &[OpCode]: Iterator`
           `[OpCode]: Iterator`
           which is required by `&mut [OpCode]: Iterator`

我得到以下 而有一个fold()函数&amp;它无法称呼它,因为某些特征界限不满意,所以它不能称呼它,但没有以我能理解的方式说明这些界限。

那么,有人可以解释发生了什么以及如何解决吗?

So I'm building a chip-8 CPU emulator and to make copying data into the memory easier I created the following two methods:

pub struct CPU {
    // ... other unrelated fields
    pub memory: [u8; 0x1000],
}

impl CPU {
    pub fn raw_copy_to_mem(&mut self, loc: usize, data: &[u8]) {
        data.chunks(2).fold(loc, |loc, bytes| {
            self.raw_add_to_mem(loc, *bytes.first().unwrap(), *bytes.last().unwrap())
        });
    }

    pub fn raw_add_to_mem(&mut self, loc: usize, high: u8, low: u8) -> usize {
        self.memory[loc] = high; self.memory[loc + 1] = low;
        loc + 2
    }
}

Now this works for this for example:

fn make_cpu() -> processor::CPU {

   processor::CPU {
        // ... other unrelated fields
        memory: [0; 0x1000],
    }
}
#[test]
fn test_raw_memory_copy() {
    let mut cpu = make_cpu();

    let add_twice: [u8; 6] = [
        0x80, 0x14,
        0x80, 0x14,
        0x00, 0xEE,
    ];

    cpu.raw_copy_to_mem(0x100 , &add_twice);

    assert_eq!(cpu.memory[0x100..0x106], add_twice);

}

Now to make doing OpCodes easier I have the following struct and functions:

#[derive(Debug, Clone, Copy)]
pub struct OpCode(u8, u8);

impl OpCode {
    pub fn high_byte(&self) -> u8 {
        self.0
    }

    pub fn low_byte(&self) -> u8 {
        self.1
    }
}

impl From<OpCode> for u16 {
    fn from(c: OpCode) -> Self {
        (c.0 as u16) << 8 | c.1 as u16
    }
}

impl From<&OpCode> for u16 {
    fn from(c: &OpCode) -> u16 {
        c.into()
    }
}

impl OpCode {
    pub fn add(h: u8, l: u8) -> Self {
        Self (0x8 << 4 | h, (l << 4) | 4)
    }
}

And the following CPU function also works great:

impl CPU {
    pub fn add_to_mem(&mut self, loc: usize, oc: &OpCode) -> usize {
        self.memory[loc] = oc.high_byte(); self.memory[loc + 1] = oc.low_byte();
        loc + 2
    }
}

The problem occurs when I try to add a copy_to_mem() function for the OpCode struct:

impl CPU {
    pub fn copy_to_mem(&mut self, loc: usize, data: &[OpCode]) {
        data.fold(loc, |loc, opcode| {
            self.add_to_mem(loc, opcode)
        });
    }
}

I get the following error that I only vaguely understand:

error[E0599]: the method `fold` exists for reference `&[OpCode]`, but its trait bounds were not satisfied
  --> src/processor.rs:21:14
   |
21 |         data.fold(loc, |loc, bytes| {
   |              ^^^^ method cannot be called on `&[OpCode]` due to unsatisfied trait bounds
   |
   = note: the following trait bounds were not satisfied:
           `&[OpCode]: Iterator`
           which is required by `&mut &[OpCode]: Iterator`
           `[OpCode]: Iterator`
           which is required by `&mut [OpCode]: Iterator`

I get that it's saying that whilst there is a fold() function & that it can't call it because some trait bounds weren't satisfied so it can't call it but it doesn't state what those bounds are in a way that I can understand.

So, could someone explain what is going on, and how to fix?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

残花月 2025-01-25 15:43:28

该错误消息具有误导性:问题是您尝试使用切片作为迭代器,但事实并非如此。要获取切片的迭代器,请调用它的 iter() 方法(或 iter_mut() 用于可变迭代器)。

pub fn copy_to_mem(&mut self, loc: usize, data: &[OpCode]) {
    data.iter().fold(loc, |loc, bytes| {
        self.add_to_mem(loc, bytes.high_byte())
    });
}

请注意,它仍然会出错:

error[E0308]: mismatched types
  --> src/lib.rs:60:34
   |
60 |             self.add_to_mem(loc, bytes.high_byte())
   |                                  ^^^^^^^^^^^^^^^^^ expected `&OpCode`, found `u8`

因为 add_to_mem 需要 &OpCodebytes 确实是 &OpCode > bytes.high_byte()u8

The error message is misleading: the problem is that you're trying to use a slice as an iterator, but it isn't. To obtain an iterator for the slice, call it's iter() method (or iter_mut() for mutable iterator).

pub fn copy_to_mem(&mut self, loc: usize, data: &[OpCode]) {
    data.iter().fold(loc, |loc, bytes| {
        self.add_to_mem(loc, bytes.high_byte())
    });
}

Note that it'll still error with:

error[E0308]: mismatched types
  --> src/lib.rs:60:34
   |
60 |             self.add_to_mem(loc, bytes.high_byte())
   |                                  ^^^^^^^^^^^^^^^^^ expected `&OpCode`, found `u8`

Because add_to_mem expects &OpCode but while bytes is indeed &OpCode bytes.high_byte() is u8.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文