rust - 为什么在基于类型实现宏时需要在 <$a> 中使用尖括号?

标签 rust macros

我可以实现一个采用这样的类型的宏:

trait Boundable<A> {
    fn max_value() -> A;
}

impl Boundable<u8> for u8 {
    fn max_value() -> u8 { u8::MAX }
}
当我转动 impl成一个宏,为什么我需要用尖括号包围类型本身,就像这样?
macro_rules! impl_boundable {
    ($a:ty) => {
        impl Boundable<$a> for $a {
            fn max_value() -> $a { <$a>::MAX }
        }
    };
}

impl_boundable!(i8);
特别是<$a>::MAX .没有它,编译器会给我错误 missing angle brackets in associated item path .我很困惑为什么宏代码需要与非宏代码不同。
playground

最佳答案

语法是 _path_::item ,不是 _type_::item .有效路径包括标识符和 <T>类型 T .
u8::MAX , u8被允许是因为它是一个标识符,而不是因为它是一种类型。 [u8; 1]::item不被允许。
如果您的宏需要 $a:ident , 而不是 $a:ty ,它将按原样使用也是标识符的类型,如 u8 .但是,接受类型 $a:ty ,从类型创建路径的通用方法是使用尖括号 <$a> .
您的宏也可以选择直接接受路径:$a:path .但是你很可能会遇到bug #48067 :解析器无法弄清楚如何从较小的路径段组成路径。在 use $a as base; base::MAX 的工单中,有针对这种情况的解决方法。 .

关于rust - 为什么在基于类型实现宏时需要在 <$a> 中使用尖括号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66286508/

相关文章:

rust - 如何使用非平凡的初始化器声明/管理常量

macros - 如何匹配 Rust 宏中表达式的类型?

functional-programming - Clojure 中的这个宏有什么问题?

c - 如何评估嵌套的预处理器宏

macros - Clojure 宏和符号绑定(bind)

mysql - 使用 Diesel 的声明式架构定义

rust - 如何使用 Piston 图像箱中的 read_scanline?

reference - `&` 和 `ref` 有什么区别?

scala - 宏采用类主体,消除显式新运算符?

macros - 方案:用于代码复制的宏或高阶函数?