27

次のようなカスタム構造体があります。

struct MyStruct {
    first_field: i32,
    second_field: String,
    third_field: u16,
}

プログラムで構造体フィールドの数を取得することは可能ですか (たとえば、メソッド呼び出しを介してfield_count()):

let my_struct = MyStruct::new(10, "second_field", 4);
let field_count = my_struct.field_count(); // Expecting to get 3

この構造体の場合:

struct MyStruct2 {
    first_field: i32,
}

...次の呼び出しが返され1ます:

let my_struct_2 = MyStruct2::new(7);
let field_count = my_struct2.field_count(); // Expecting to get count 1

ような API はありfield_count()ますか、それともマクロ経由でのみ取得できますか?

これがマクロで達成できる場合、どのように実装する必要がありますか?

4

2 に答える 2

9

構造体自体がマクロによって生成される場合は可能です。この場合、ここに示すように、マクロに渡されたトークンをカウントするだけです。それが私が思いついたものです:

macro_rules! gen {
    ($name:ident {$($field:ident : $t:ty),+}) => {
        struct $name { $($field: $t),+ }
        impl $name {
            fn field_count(&self) -> usize {
                gen!(@count $($field),+)
            }
        }
    };
    (@count $t1:tt, $($t:tt),+) => { 1 + gen!(@count $($t),+) };
    (@count $t:tt) => { 1 };
}

遊び場(いくつかのテストケース付き)

このアプローチの欠点 (1 つ - 他にもある可能性があります) は、この関数に属性を追加するのが簡単ではないことです (たとえば、その上の#[derive(...)]何かに)。もう 1 つの方法は、カスタムの派生マクロを作成することですが、これについては今はお話しできません。

于 2019-01-14T08:24:48.380 に答える