我有这个枚举:
enum Foo {
Bar,
Baz(String),
// And maybe some other variants
}
我发现自己经常与预定义的Baz
字符串进行模式匹配。
match foo_instance {
Foo::Baz(ref x) => match x.as_str() {
"stuff" => ...,
"anotherstuff" => ...,
},
// Other match cases...
}
有时我只匹配一个案例,有时候是Foo::Baz
的4-5个案例。在后一种情况下,双match
并不会让我感到非常困扰,实际上这个分组在这一点上是有意义的。如果我只匹配Foo::Baz
的一个案例,那感觉就不对了。我真正希望能做的是:
const STUFF: Foo = Foo::Baz("stuff".to_string());
const ANOTHER_STUFF: Foo = Foo::Baz("anotherstuff".to_string());
match foo_instance {
&STUFF => ...,
&ANOTHER_STUFF => ...,
// Other match cases...
}
但当然,由于to_string()
来电,这不会起作用(而且我还需要派生Eq
特质才能与const
匹配奇怪。这对我来说也许是一个问题。)有没有办法模仿这个?例如,使用宏,我可以这样做:
const STUFF: Foo = magic!(Foo::Baz("stuff".to_string());
const ANOTHER_STUFF: Foo = magic!(Foo::Baz("anotherstuff".to_string()));
// Or any other thing that can mimic top level behavior,
// I may create these constants dynamically at program start, that would work too.
match foo_instance {
another_magic!(STUFF) => ...,
another_magic!(ANOTHER_STUFF) => ...,
// Other match cases...
}
一般来说,我希望能够有一个包含堆分配数据的枚举的常量变体(在这种情况下为String
),这样我就可以在{{1 }} 案件。处理这个问题的最佳方法是什么?
答案 0 :(得分:2)
您无法在当前Rust,句号中创建具有堆分配数据的常量。
也许将来可以创建一个const FOO: String
,但在此之前还有很多工作要做并做出决定。
使用宏
宏不是魔术。它们只允许您编写某些类型的代码,您可以使用新语法编写这些代码。由于您无法创建这些常量,因此您无法编写宏来创建它们。
我想以某种方式将匹配大小写的所有左侧提取到常量或类似的东西。比赛后卫对我没有帮助(是的,它消除了双重比赛的需要,但它是我的最后手段。
同样
map()
我的枚举不会起作用,因为它不是结构,我需要在map
中匹配。
创建并行类型似乎太奇怪了。
我可以创建一个const
static &str
并与那些解决方案匹配,但这会引发另一个问题。这些常量只有字符串,并且它们没有全部含义。
只有一种解决方案可以满足我提供的解决方案所需的解决方案,而且我发现这个解决方案太冗长了。
我有很多像这样的枚举,并且很难为每个枚举创建并行类型,除此之外,解决方案只是冗长。
对于可以使用已经丢弃的替代解决方案的其他读者,请参阅:
如需进一步阅读,请参阅: