Rust 是否有等效于 C++ 的 decltype() 来获取表达式的类型?

Mih*_*hir 9 rust

我的代码看起来像:

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);
}
Run Code Online (Sandbox Code Playgroud)

上面的代码将屏蔽位图。在上面的例子中,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]
        }
    };
}
Run Code Online (Sandbox Code Playgroud)

但是我必须将类型传递给宏才能完成此操作。decltype()我可以使用 C++ 之类的东西吗?

She*_*ter 8

No, Rust does not have the ability to get the type of an arbitrary expression. typeof is a reserved keyword to potentially allow it in the future:

fn main() {
    let a: i32 = 42;
    let b: typeof(a) = a;
}
Run Code Online (Sandbox Code Playgroud)
fn main() {
    let a: i32 = 42;
    let b: typeof(a) = a;
}
Run Code Online (Sandbox Code Playgroud)

There are RFCs suggesting that it be added.

See also:


For your specific case, I would use traits instead:

error[E0516]: `typeof` is a reserved keyword but unimplemented
 --> src/main.rs:3:12
  |
3 |     let b: typeof(a) = a;
  |            ^^^^^^^^^ reserved keyword
Run Code Online (Sandbox Code Playgroud)

You could use macros to implement the trait however:

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);
}
Run Code Online (Sandbox Code Playgroud)