在我的程序中,我表示某些对象字段的更改历史记录,如下所示:
struct FieldChange {
property_name: &'static str,
// some other fields
}
let history = Vec<FieldChange>::new();
Run Code Online (Sandbox Code Playgroud)
我这样处理:
match field_change.property_name {
"name" => // do something,
"age" => // do something,
_ => {}
}
Run Code Online (Sandbox Code Playgroud)
为了提高可读性并方便将来的重构,我想写这样的内容:
match field_change.property_name {
nameof(Person::name) => // do something,
nameof(Person::age) => // do something,
_ => {}
}
Run Code Online (Sandbox Code Playgroud)
wherenameof生成&str字段的表示,类似于nameofC# 中的。
我正在寻找的要点是编译器可以验证字段是否存在(例如,在本例中,是否Person确实有name和age字段)。在 Rust 中是否可以像这样提取字段名称?
不,但你可以获得与宏类似的东西。因为宏可以解决一切! [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);
}
Run Code Online (Sandbox Code Playgroud)
如果您尝试使用不存在的名称,您会得到如下所示的内容:
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);
}
Run Code Online (Sandbox Code Playgroud)
或者像这样:
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);
|> ^
Run Code Online (Sandbox Code Playgroud)
[1]:注意:宏实际上并不能解决所有问题。
| 归档时间: |
|
| 查看次数: |
1414 次 |
| 最近记录: |