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

Rust 是否可以访问函数签名或声明的结构成员类型?,rust,Rust,在宏中定义实现时,访问struct members类型可能很有用,以避免将其作为额外参数传递。(见附件) impl PartialEq for MyStruct{…} 有没有一种方法可以访问结构成员的类型而不事先知道它是哪种类型 impl PartialEq<typeof(MyStruct.member)> for MyStruct { ... } impl PartialEq for MyStruct{…} 如果有帮助的话,这是我为什么有兴趣这样做的一个简短示例: stru

在宏中定义实现时,访问struct members类型可能很有用,以避免将其作为额外参数传递。(见附件)

impl PartialEq for MyStruct{…}
有没有一种方法可以访问结构成员的类型而不事先知道它是哪种类型

impl PartialEq<typeof(MyStruct.member)> for MyStruct { ... }
impl PartialEq 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?
    }
}
struct\u bitflag\u impl!(
发布结构MyFlag(u8);,
MyFlag,u8);
//^^如何避免使用此额外参数?
//(由“`impl PartialEq for$p``使用)
//无法从“MyFlag.0”中找到它吗?
//宏
宏规则!结构\u位标志\u impl{
($struct\u p\u def:item,$p:ident,$t\u internal:ty)=>{
#[派生(PartialEq、Eq、复制、克隆、调试)]
$struct\u p\u def
impl::std::ops::比特和$p{
类型输出=$p;
fn位(self,_rhs:$p)->$p{$p(self.0&_rhs.0)}
}
impl::std::ops::BitOr for$p{
类型输出=$p;
fn比特(self,_-rhs:$p)->$p{$p(self.0 | u-rhs.0)}
}
impl::std::ops::位异或$p{
类型输出=$p;
fn位异或(self,_-rhs:$p)->$p{$p(self.0^u-rhs.0)}
}
impl::std::ops::不适用于$p{
类型输出=$p;
fn not(self)->$p{$p(!self.0)}
}
//支持与基类型进行比较。
为$p执行PartialEq{
fn eq(自身和其他:内部和t_)->bool{
self.0==*其他
}
}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//如何避免在此处使用“t_internal”?
}
}
否,不存在可在类型位置使用的常规
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();
}
这样,您只需指定所有内容一次。然而,这显然只适用于一种元组结构定义,而不是所有类型的项。但是您的用例表明您或多或少只对这个特殊情况感兴趣


如果希望允许不同类型的结构定义,只需向宏中添加更多宏规则以允许不同的语法。要查看示例。但是这还可以进一步扩展。

这段硬代码不是对结构及其内部成员都是公共/私有的吗?例如,您可能需要执行
struct-Peter(pub-u8)
pub-struct-Peter(u8)
@ideasman42绝对地,这是针对特定情况的硬编码。如果您想要
pub
和非
pub
的灵活性,您可以添加更多宏“arms”。。。让我尝试构建一个更好的版本,并将其链接到问题中。请待命;-)很好,更新了我的代码以使用这种宏样式-仍然不确定如何进行
Peter(u8)
Peter(pub u8)
更新,结构可见性和内部变量可见性都可以进行模式匹配、编辑;来自@keepr的注释,这可以由
custom\u-deriver
处理,请参见:**/custom\u-deriver/index.html
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();
}