基于@ ker的的建议,下面是基于固定大小的字节串创建的常数标识符便携宏:
警告:但是也有一些不是很明显这些常量一些限制(见下面的注意事项)。
以下宏支持:
const MY_ID: u16 = u16_code!(b"ID");
const MY_WORD: u32 = u32_code!(b"WORD");
const MY_LONG: u64 = u64_code!(b"LONGWORD");
实现:
#[cfg(target_endian = "little")]
#[macro_export]
macro_rules! u16_code {
($w:expr) => {
((($w[0] as u16) << 0) |
(($w[1] as u16) << 8) |
((*$w as [u8; 2])[0] as u16 * 0))
}
}
#[cfg(target_endian = "big")]
#[macro_export]
macro_rules! u16_code {
($w:expr) => {
((($w[1] as u16) << 0) |
(($w[0] as u16) << 8) |
((*$w as [u8; 2])[0] as u16 * 0))
}
}
#[cfg(target_endian = "little")]
#[macro_export]
macro_rules! u32_code {
($w:expr) => {
((($w[0] as u32) << 0) |
(($w[1] as u32) << 8) |
(($w[2] as u32) << 16) |
(($w[3] as u32) << 24) |
((*$w as [u8; 4])[0] as u32 * 0))
}
}
#[cfg(target_endian = "big")]
#[macro_export]
macro_rules! u32_code {
($w:expr) => {
((($w[3] as u32) << 0) |
(($w[2] as u32) << 8) |
(($w[1] as u32) << 16) |
(($w[0] as u32) << 24) |
((*$w as [u8; 4])[0] as u32 * 0))
}
}
#[cfg(target_endian = "little")]
#[macro_export]
macro_rules! u64_code {
($w:expr) => {
((($w[0] as u64) << 0) |
(($w[1] as u64) << 8) |
(($w[2] as u64) << 16) |
(($w[3] as u64) << 24) |
(($w[4] as u64) << 32) |
(($w[5] as u64) << 40) |
(($w[6] as u64) << 48) |
(($w[7] as u64) << 56) |
((*$w as [u8; 8])[0] as u64 * 0))
}
}
#[cfg(target_endian = "big")]
#[macro_export]
macro_rules! u64_code {
($w:expr) => {
((($w[7] as u64) << 0) |
(($w[6] as u64) << 8) |
(($w[5] as u64) << 16) |
(($w[4] as u64) << 24) |
(($w[3] as u64) << 32) |
(($w[2] as u64) << 40) |
(($w[1] as u64) << 48) |
(($w[0] as u64) << 56) |
((*$w as [u8; 8])[0] as u64 * 0))
}
}
注1),检查需要与恒定的,因为分开地进行或运算的尺寸线语句在常量表达式中不受支持(E0016
)。
我也宁愿在一个宏内使用if cfg!(target_endian = "big")
,但常数的相同限制阻止它。
注2)有可能使用这些宏用于非恒定的输入,其中,所述参数可以被实例化的每个字节(和可能为尺寸完整性检查)的问题。我看着分配一个变量,但这也会导致错误E0016
。
注3)尽管Rust允许将这些值声明为const
,但它们不能在match
语句中使用。
如:
error[E0080]: constant evaluation error
--> src/mod.rs:112:23
|
112 | const MY_DATA: u32 = u32_code!(b"DATA");
| ^^^^^^^^^^^^^^^^^^ the index operation on const values is unstable
|
note: for pattern here
--> src/mod.rs:224:13
|
224 | MY_DATA => {
| ^^^^^^^
*我无法弄清楚如何使用时,位移上文字字节串*实现。请提供此前的工作,当您提出问题 –
@ker时,我开始这样做,但之后有一个问题被标记为“代码审查”,我发现如果我发布示例代码,答案会过分集中于分离天真的代码,而不是什么可能的,特别是当我的方法可能是错的时候。不过,我不介意举例说明。 – ideasman42