在宏内解构枚举时未找到解构项

问题描述 投票:0回答:1
macro_rules! declare_types {
    ($($token:ident -> $inner:ty, $to_string:expr,)*) => {
        enum Value {
            $($token($inner),)*
        }

        impl Display for Value {
            fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> {
                match self {
                    $(
                        Self::$token(inner)=>write!(fmt,"{}",$to_string)?,
                    )*
                };
                Ok(())
            }
        }
    }
}

declare_types!(
    String -> String, inner,
);

但是,该代码会导致编译器错误:

cannot find value `inner` in this scope
not found in this scope

当我将鼠标悬停在

inner
上时,IDE 会正确显示它:

ide hover

此外,通过展开宏并将其粘贴回来,它可以正常工作而不会出现任何错误。

rust enums macros destructuring rust-macros
1个回答
0
投票

由于宏卫生,在宏内部创建的标识符(如

inner
中的
Self::$token (inner)
)与在调用代码中创建的标识符(如
inner
中的
declare_types!(String -> String, inner);
)不同。如果您希望能够在显示的表达式中使用标识符,则需要将此标识符从调用者传递给宏:

macro_rules! declare_types {
    ($($token:ident -> $inner:ty, $id: ident, $to_string:expr,)*) => {
        enum Value {
            $($token($inner),)*
        }

        impl std::fmt::Display for Value {
            fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
                match self {
                    $(
                        Self::$token($id)=>write!(fmt,"{}",$to_string)?,
                    )*
                };
                Ok(())
            }
        }
    }
}

declare_types!(
    String -> String, inner, inner,
);

游乐场

© www.soinside.com 2019 - 2024. All rights reserved.