Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 如何从文本字节表达式构造常量整数?_Rust_Byte_Constants_Data Conversion - Fatal编程技术网

Rust 如何从文本字节表达式构造常量整数?

Rust 如何从文本字节表达式构造常量整数?,rust,byte,constants,data-conversion,Rust,Byte,Constants,Data Conversion,有没有一种方法可以从文本字节表达式构造const整数,可以使用字节字符串或构造整数的宏 例如: const MY_ID: u16 = u16_code!(ID); const MY_WORD: u32 = u32_code!(WORD); const MY_LONG: u64 = u64_code!(LONGWORD); 或者类似的东西,传入b“ID”而不是ID* 当传递的字符数也错误时,它应该无法编译,这是我在对文本字节字符串使用位移位时无法理解的 下面是一个简单的示例,它可以在基本级

有没有一种方法可以从文本字节表达式构造
const
整数,可以使用字节字符串或构造整数的宏

例如:

const MY_ID:   u16 = u16_code!(ID);
const MY_WORD: u32 = u32_code!(WORD);
const MY_LONG: u64 = u64_code!(LONGWORD);
或者类似的东西,传入
b“ID”
而不是
ID
*

当传递的字符数也错误时,它应该无法编译,这是我在对文本字节字符串使用位移位时无法理解的


下面是一个简单的示例,它可以在基本级别上工作,但无法确保参数大小正确

// const MY_ID: u16 = u16_code!(b"ID");
#[cfg(target_endian = "little")]
macro_rules! u16_code {
    ($w:expr) => { ((($w[0] as u16) <<  0) | (($w[1] as u16) <<  8)) }
}
#[cfg(target_endian = "big")]
macro_rules! u16_code {
    ($w:expr) => { ((($w[1] as u16) <<  0) | (($w[0] as u16) <<  8)) }
}
//const MY\u ID:u16=u16\u code!(b)“身份证”);
#[cfg(target_endian=“little”)]
宏规则!u16_码{

($w:expr)=>{(($w[0]作为u16)您可以通过索引到数组中并将部分位移到正确的位置来为每种类型构建宏

((b"ID"[0] as u16) << 8) | (b"ID"[1] as u16)

((b“ID”[0]为u16)根据@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))
    }
}

我不知道如何在对文本字节字符串使用位移位时实现。请在您询问question@ker,我开始这样做,但随后将其中一个问题标记为“代码审阅”,我发现如果我发布示例代码,答案太多地集中在挑选幼稚的代码,而不是可能的,尤其是当我的方法一开始可能是错误的时候。尽管如此,我不介意发布示例。也许一个
match
表达式而不是
let
语句会起作用?
match$w{w=>…}
与此上下文中几乎所有聪明的技巧一样,它给出了:
错误[E0016]:常量中的块仅限于项和尾部表达式。如果将
匹配
包装在块中,则会出现内部编译器错误(oops!)。然后我能想到的唯一解决方案是
常量fn
(这是一个不稳定的特性),将表达式绑定到参数(并且
const fn
还提供类型检查)。不幸的是,使用此方法创建的常量不能用作匹配语句中的值(导致错误E0080,请参阅我自己答案中的注释).正确,这是一个已经存在了一段时间的夜间功能。您可以打开RFC使其稳定。
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 => {
    |             ^^^^^^^