在 Rust 中是否有类似于 C# 的 nameof() 的函数?

7
在我的程序中,我按照以下方式表示某些对象字段的更改历史:
struct FieldChange {
    property_name: &'static str,
    // some other fields
}

let history = Vec<FieldChange>::new();

我这样处理它:
match field_change.property_name {
    "name" => // do something,
    "age"  => // do something,
    _      => {}
}

为了提高可读性并便于未来重构,我想像这样写:
match field_change.property_name {
    nameof(Person::name) => // do something,
    nameof(Person::age)  => // do something,
    _                    => {}
}

nameof 生成一个字段的 &str 表示,类似于 C# 中的 nameof

我想要强调的主要点是,编译器可以验证字段是否存在(例如,在本例中,Person 是否确实有 nameage 字段)。在 Rust 中是否可能像这样提取字段名?

1个回答

6
不,但是你可以使用宏来得到类似的功能。因为宏解决了所有问题![1]
macro_rules! name_of {
    ($name:ident in $ty:ty) => {
        {
            #[allow(dead_code)]
            fn dummy(v: $ty) {
                let _ = &v.$name;
            }
            stringify!($name)
        }
    };

    ($name:ident) => {
        {
            let _ = &$name;
            stringify!($name)
        }
    };
}

struct Person {
    // 255 years should be enough for anybody.
    age: u8,
    name: String,
}

fn main() {
    let p = Person { age: 27, name: "John Smith".into() };
    println!("The {} of Person {} is: {}", name_of!(age in Person), name_of!(p), p.age);
}

如果您尝试使用不存在的名称,您将会得到类似于以下内容的提示:

error: unresolved name `q`. Did you mean `p`? [--explain E0425]
  --> <anon>:28:78
28 |>     println!("The {} of Person {} is: {}", name_of!(age in Person), name_of!(q), p.age);
   |>                                                                              ^

或者像这样:
error: attempted access of field `shoe_size` on type `Person`, but no field with that name was found
 --> <anon>:6:26
6 |>                 let _ = &v.$name;
  |>                          ^

[1]: 注意:宏并不是解决所有问题的万能钥匙。


1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - xilec
啊,对了;我忘记了match部分。这个我无能为力:如果你想断言名称存在,你必须做一些使用它的事情,而你不能在模式中做到这一点。不,过程宏不会有所帮助,因为它们在这里与常规宏具有相同的限制:它们无法看到名称。它们将必须发出类似的东西。 - DK.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接