【问题标题】:Does Rust have an equivalent to C++'s decltype() to get the type of an expression?Rust 是否有等效于 C++ 的 decltype() 来获取表达式的类型?
【发布时间】:2020-11-18 09:59:15
【问题描述】:

我的代码如下:

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);
}

以上代码将屏蔽位图。在上面的示例中,0b_1111_1111[..5] 屏蔽后将变为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() 之类的东西吗?

【问题讨论】:

  • 如果您使用mem::size_of_val ($bitmap) 而不是mem::size_of::&lt;$ty&gt;()~0 而不是&lt;$ty&gt;::MAX,则可以删除该类型的所有实例(因为无论如何您的宏只对无符号整数类型有意义)。
  • @Jmb,mem::size_of_val() 是否会在编译时被任何优化解释?我试过你之前说的。 mem::size_of() 是 const func 所以它会在编译时得到解决,但我不确定 size_of_val
  • 根据the docssize_of_valsize_of::&lt;T&gt;() 相同,除非在编译时无法知道T 的大小,在这种情况下,它会在运行时进行评估,而size_of::&lt;T&gt;() 编译失败。

标签: rust


【解决方案1】:

不,Rust 没有能力获取任意表达式的类型。 typeof 一个保留关键字,将来可能会允许它:

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);
}

您可以使用宏来实现特征

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);

【讨论】:

    猜你喜欢
    • 2013-10-14
    • 1970-01-01
    • 1970-01-01
    • 2018-09-15
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多