是否可以访问函数签名或声明的结构成员的类型?

ide*_*n42 5 rust

在宏中定义实现时,访问struct成员类型以避免必须将其作为额外参数传递可能很有用.(见这个问题)

impl PartialEq<u32> for MyStruct { ... }
Run Code Online (Sandbox Code Playgroud)

有没有办法在不事先知道它是哪种类型的情况下访问结构成员的类型?

impl PartialEq<typeof(MyStruct.member)> for MyStruct { ... }
Run Code Online (Sandbox Code Playgroud)

如果它有用,这是为什么我有兴趣这样做的缩写示例:

struct_bitflag_impl!(
    pub struct MyFlag(u8);,
    MyFlag, u8);

//          ^^ how to avoid having this extra arg?
//             (Used by ``impl PartialEq<$t_internal> for $p``)
//             couldn't it be discovered from `MyFlag.0` ?

// the macro

macro_rules! struct_bitflag_impl {
    ($struct_p_def: item, $p:ident, $t_internal:ty) => {

        #[derive(PartialEq, Eq, Copy, Clone, Debug)]
        $struct_p_def

        impl ::std::ops::BitAnd for $p {
            type Output = $p;
            fn bitand(self, _rhs: $p) -> $p { $p(self.0 & _rhs.0) }
        }
        impl ::std::ops::BitOr for $p {
            type Output = $p;
            fn bitor(self, _rhs: $p) -> $p { $p(self.0 | _rhs.0) }
        }
        impl ::std::ops::BitXor for $p {
            type Output = $p;
            fn bitxor(self, _rhs: $p) -> $p { $p(self.0 ^ _rhs.0) }
        }

        impl ::std::ops::Not for $p {
            type Output = $p;
            fn not(self) -> $p { $p(!self.0) }
        }

        // support comparison with the base-type.
        impl PartialEq<$t_internal> for $p {
            fn eq(&self, other: &t_internal) -> bool {
                self.0 == *other
            }
        }
        // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        //       How to avoid using 't_internal' here?
    }
}
Run Code Online (Sandbox Code Playgroud)

Luk*_*odt 5

typeof(Type::field)不,不存在可用于类型位置的将军。


关于问题中的示例,看起来您正在期待一种特殊的项目:只有一个字段的元组结构。$item因此,您可以自己模拟语法,而不是接受片段:

macro_rules! foo {
    (pub struct $name:ident ( $ty:ident ) ) => {
        pub struct $name($ty);

        impl $name {
            pub fn bar() { 
                println!("{}", stringify!($ty)); 
            }
        }
    }
}

foo!(
    pub struct Peter(u8)
);

fn main() {
    Peter::bar();
}
Run Code Online (Sandbox Code Playgroud)

这样您只需指定所有内容一次。然而,这显然只适用于一种元组结构定义,而不适用于所有类型的项目。但您的用例表明您或多或少只对这种特殊情况感兴趣。

如果您想允许不同类型的结构定义,您只需向宏添加更多宏规则以允许不同的语法。要查看示例,这里是允许pubpub元组结构定义的代码。但这还可以进一步扩大。