是否可以访问用于函数签名或声明的结构成员的类型? [英] Is it possible to access the type of a struct member for function signatures or declarations?

查看:30
本文介绍了是否可以访问用于函数签名或声明的结构成员的类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When defining implementations in macros, it might be useful to access a struct members type to avoid having to pass it as an extra argument. (see this question)

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

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

Is there a way to access the type of a struct member without knowing in advance which type it is?

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

<小时>

如果有帮助,以下是我感兴趣的原因的简短示例:


In case it's helpful, this is an abbreviated example of why I'm interested to do this:

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

推荐答案

不,一般的typeof(Type::field)可用于类型位置的不存在.

No, a general typeof(Type::field) that can be used in type position does not exist.

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

Regarding the example in the question, it looks like you are expecting a special kind of item: a tuple-struct with only one field. So, instead of accepting an $item fragment, you can simulate the syntax yourself:

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();
}

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

That way you only have to specify everything once. However, this obviously only works with one kind of tuple-struct definition, not all kinds of items. But your use case suggests that you are more or less only interested in this special case.

如果你想允许不同类型的结构定义,你只需要在宏中添加更多的宏规则以允许不同的语法.要查看示例,这里是允许 pub 和非pub 元组结构定义.但这可以进一步扩展.

If you want to allow different kinds of struct definitions, you just need to add more macro-rules to the macro to allow for different syntax. To see an example, here is code to allow for pub and non-pub tuple-struct definitions. But this could be expanded even more.

这篇关于是否可以访问用于函数签名或声明的结构成员的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆