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

时间:2016-11-13 10:57:24

标签: rust

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

impl PartialEq<u32> for MyStruct { ... }

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

impl PartialEq<typeof(MyStruct.member)> for MyStruct { ... }

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

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?
    }
}

1 个答案:

答案 0 :(得分:4)

不,可以在类型位置使用的一般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();
}

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

如果要允许不同类型的结构定义,只需要向宏添加更多宏规则以允许不同的语法。要查看示例here is code to allow for pub and non-pub tuple-struct definitions。但这可以进一步扩大。