gpt4 book ai didi

struct - Rust:使用两个u8结构字段作为u16

转载 作者:行者123 更新时间:2023-12-03 11:28:13 27 4
gpt4 key购买 nike

对于Gameboy模拟器,您有两个用于寄存器A和F的u8字段,但有时可以将它们作为AF(组合的u16寄存器)进行访问。
在C语言中,您可以执行以下操作:

struct {
union {
struct {
unsigned char f;
unsigned char a;
};
unsigned short af;
};
};
(摘自 here)
在Rust中,最好没有 unsafe,是否有一种方法可以访问两个u8作为 registers.a/ registers.f,还可以将它们用作u16 registers.af

最佳答案

我可以给您几种方法。第一个是简单直接的不安全模拟,但没有样板,第二个是安全但明确的。

  • rust 中的联合非常相似,因此您可以将其翻译为:
  • #[repr(C)]
    struct Inner {
    f: u8,
    a: u8,
    }

    #[repr(C)]
    union S {
    inner: Inner,
    af: u16,
    }

    // Usage:

    // Putting data is safe:
    let s = S { af: 12345 };
    // but retrieving is not:
    let a = unsafe { s.inner.a };
  • 或者,您也可以手动执行包裹在结构中的所有显式强制转换:
  • #[repr(transparent)]
    // This is optional actually but allows a chaining,
    // you may remove these derives and change method
    // signatures to `&self` and `&mut self`.
    #[derive(Clone, Copy)]
    struct T(u16);

    impl T {
    pub fn from_af(af: u16) -> Self {
    Self(af)
    }

    pub fn from_a_f(a: u8, f: u8) -> Self {
    Self::from_af(u16::from_le_bytes([a, f]))
    }

    pub fn af(self) -> u16 {
    self.0
    }

    pub fn f(self) -> u8 {
    self.0.to_le_bytes()[0]
    }

    pub fn set_f(self, f: u8) -> Self {
    Self::from_a_f(self.a(), f)
    }

    pub fn a(self) -> u8 {
    self.0.to_le_bytes()[1]
    }

    pub fn set_a(self, a: u8) -> Self {
    Self::from_a_f(a, self.f())
    }
    }

    // Usage:

    let t = T::from_af(12345);
    let a = t.a();

    let new_af = t.set_a(12).set_f(t.f() + 1).af();

    关于struct - Rust:使用两个u8结构字段作为u16,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62831700/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com