有没有一种方法可以从一个字节表达式构造一个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)) }
}
型
*****参见相关问题:Is there a byte equivalent of the 'stringify' macro?
3条答案
按热度按时间r6l8ljro1#
你可以为每种类型建立一个宏,方法是在数组中建立索引,并将部分移位到正确的位置。
字符串
您可以使用来自
$e:expr
的宏替换$e
来替换b"ID"
。为了实现长度检查,可以插入一个无用的
*$e as [u8; 2]
,如果类型不匹配,它将无法编译。aydmsdu92#
根据@ker的建议,这里有一些可移植的宏,它们基于固定大小的字节字符串创建常量标识符:
**警告:**这些常量有一些限制,这些限制并不明显(见下面的注解)。
以下宏支持:
字符串
实施:
型
**注1)**检查需要与常量进行或运算的大小的行,因为常量表达式中不支持单独的语句(
E0016
)。我也更喜欢在一个宏中使用
if cfg!(target_endian = "big")
,但常量的相同限制阻止了它。**Note 2)**使用这些宏进行非常量输入可能会出现问题,其中参数可以为每个字节示例化 (可能还有大小的健全性检查)。我研究了分配变量,但这也导致错误
E0016
。**Note 3)**虽然Rust允许将这些值声明为
const
,但它们不能用于match
语句。例如:
型
nkcskrwz3#
使用较新的Rust版本,您可以执行以下操作:
字符串
这在处理FourCC时非常有用。
如果你想的话,你可以把它 Package 在一个宏中。