rust macro_rules假定参数的类型

vxbzzdmp  于 2023-03-23  发布在  Mac
关注(0)|答案(1)|浏览(135)

tl;dr I think 我想要一个宏声明来推断类型(如何创建这个宏?)
此宏无法编译(rust playground

macro_rules! debug_assert_none {
    ($($arg:tt),+) => {
        $(
            if cfg!(debug_assertions) {
                match $arg {
                    None => {}
                    Some(..) => panic!("not None")
                }
            }
        )+
    };
}

#[test]
fn test_debug_assert_none() {
    debug_assert_none!(None);
    debug_assert_none!(None, None);
}

因错误而失败

error[E0282]: type annotations needed
  --> src/lib.rs:15:24
   |
15 |     debug_assert_none!(None);
   |                        ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option`
   |
help: consider specifying the generic argument
   |
15 |     debug_assert_none!(None::<T>);
   |                            +++++

For more information about this error, try `rustc --explain E0282`.

如何满足假定的Option所需的类型声明?或者这段代码有其他问题?

js81xvg6

js81xvg61#

编译器如何知道它必须为一个裸None保留的大小?它不能,因为它可以容纳任何其他类型。一旦你在真实的世界的场景中使用你的宏,类型应该是可以推断的,但是如果你想传入一个裸None,你总是可以通过给它一个类型来显式地指定它;通常对于未使用的参数使用单元()

debug_assert_none!(None::<()>);

当然,你也可以改变宏来帮助类型推断,但这会限制宏只能处理一种类型的值:

macro_rules! debug_assert_none {
    ($($arg:tt),+) => {
        $(
            if cfg!(debug_assertions) {
                let x: &Option<()> = &$arg;
                match $arg {
                    None => {}
                    Some(..) => panic!("not None")
                }
            }
        )+
    };
}

相关问题