我的代码如下所示:

macro_rules! mask {
    ($bitmap: tt, [..$count: tt], for type = $ty: ty) => {
        {
            let bit_count = std::mem::size_of::<$ty>() * 8;
            let dec_bit_count = bit_count - 1;
            $bitmap & [(1 << ($count & dec_bit_count)) - 1, <$ty>::MAX][((($count & !dec_bit_count)) != 0) as usize]
        }
    };
}

fn main() {
    let bitmap: u8 = 0b_1111_1111;
    let masked_bitmap = mask!(bitmap, [..5], for type = u8);
    println!("{:#010b}", masked_bitmap);
}

上面的代码将屏蔽位图.在上面的例子中,被[..5]掩盖的0b_1111_1111将变成0b_0001_1111.

我希望我的宏是这样的:

macro_rules! mask {
    ($bitmap: tt, [..$count: tt]) => {
        {
            let bit_count = std::mem::size_of::<decltype($bitmap)>() * 8;
            let dec_bit_count = bit_count - 1;
            $bitmap & [(1 << ($count & dec_bit_count)) - 1, <decltype($bitmap)>::MAX][((($count & !dec_bit_count)) != 0) as usize]
        }
    };
}

但我必须将类型传递给宏才能完成.C++中有decltype()种东西我可以使用吗?

推荐答案

不,Rust无法获取任意表达式的类型.typeof is保留关键字,以便将来可能允许:

fn main() {
    let a: i32 = 42;
    let b: typeof(a) = a;
}
error[E0516]: `typeof` is a reserved keyword but unimplemented
 --> src/main.rs:3:12
  |
3 |     let b: typeof(a) = a;
  |            ^^^^^^^^^ reserved keyword

有一些RFC建议添加它.

另见:


对于你的具体情况,我会使用特征:

use std::ops::RangeTo;

trait Mask {
    fn mask(self, range: RangeTo<usize>) -> Self;
}

impl Mask for u8 {
    #[inline]
    fn mask(self, range: RangeTo<usize>) -> Self {
        // Feel free to make this your more complicated bitwise logic
        let mut m = 0;
        for _ in 0..range.end {
            m <<= 1;
            m |= 1;
        }
        self & m
    }
}


fn main() {
    let bitmap: u8 = 0b_1111_1111;
    let masked_bitmap = bitmap.mask(..5);
    println!("{:#010b}", masked_bitmap);
}

但是,您可以使用宏创建implement the trait:

macro_rules! impl_mask {
    ($($typ:ty),*) => {
        $(
            impl Mask for $typ {
                #[inline]
                fn mask(self, range: RangeTo<usize>) -> Self {
                    let mut m = 0;
                    for _ in 0..range.end {
                        m <<= 1;
                        m |= 1;
                    }
                    self & m
                }
            }
        )*
    };
}

impl_mask!(u8, u16, u32, u64, u128);

Rust相关问答推荐

有条件默认实现

在一个tauri协议处理程序中调用一个rectuc函数的推荐技术是什么?

在Rust中是否可以使用Rc自动化约束传播

什么时候和为什么S最好是按值或引用传递简单类型

`*mut[T]`与`*mut T`的区别

处理带有panic 的 Err 时,匹配臂具有不兼容的类型

我应该如何表达具有生命周期参数的类型的总排序,同时允许与不同生命周期进行比较?

一次不能多次borrow *obj作为可变对象

Rust 中多个 & 符号的内存表示

如何从borrow 的异步代码运行阻塞代码?

将多维数组转换为切片

为什么不能在 Rust 中声明静态或常量 std::path::Path 对象?

没有得到无法返回引用局部变量`queues`的值返回引用当前函数拥有的数据的值的重复逻辑

Rust 生命周期:这两种类型声明为不同的生命周期

如何将这些测试放在一个单独的文件中?

在空表达式语句中移动的值

将数据序列化为 struct 模型,其中两个字段的数据是根据 struct 中的其他字段计算的

HashMap entry() 方法使borrow 的时间比预期的长

返回 &str 但不是 String 时,borrow 时间比预期长

为什么 Rust 中的关联类型需要明确的生命周期注释?