在 Rust 中我有一个枚举
MatchType
enum MatchType {
Exact,
Lower,
Greater,
Other,
}
我将它用于我的
compare
函数来比较两个 String
。如果 MatchType
是 Exact/Lower/Greater
我想将 String
转换为 f64
并比较它们的值(如果 parse
失败,我认为比较结果是 false
)。
我可以使用一些样板代码轻松实现它,如下所示:
fn compare(str_one: String, str_two: String, match_type: MatchType) -> bool {
match match_type {
MatchType::Exact => {
let f_one = str_one.parse::<f64>();
let f_two = str_two.parse::<f64>();
if let (Ok(f_one), Ok(f_two)) = (f_one, f_two) {
f_one == f_two
} else {
false
}
},
MatchType::Lower => {
let f_one = str_one.parse::<f64>();
let f_two = str_two.parse::<f64>();
if let (Ok(f_one), Ok(f_two)) = (f_one, f_two) {
f_one < f_two
} else {
false
}
},
MatchType::Greater => {
let f_one = str_one.parse::<f64>();
let f_two = str_two.parse::<f64>();
if let (Ok(f_one), Ok(f_two)) = (f_one, f_two) {
f_one > f_two
} else {
false
}
},
MatchType::Other => false,
}
}
但我想尝试更简洁的方法:首先检查匹配是否是这三个
Exact/Lower/Greater
之一,然后解析字符串,然后像这样执行实际比较:
fn compare(str_one: String, str_two: String, match_type: MatchType) -> bool {
match match_type {
MatchType::Exact | MatchType::Lower | MatchType::Greater => {
let f_one = str_one.parse::<f64>();
let f_two = str_two.parse::<f64>();
if let (Ok(f_one), Ok(f_two)) = (f_one, f_two) {
match match_type {
MatchType::Exact => f_one == f_two,
MatchType::Lower => f_one < f_two,
MatchType::Greater => f_one > f_two,
// --- Non-exhaustive ---
_ => false,
}
} else {
false
}
},
MatchType::Other => false,
}
}
它可以工作,但内部匹配并不详尽,当然简单的
_ => false
修复了它,但我想知道是否可以以某种方式告诉 Rust 编译器,内部模式只是这 3 个枚举变体 Lower/Greater/Exact
。
我尝试使用模式绑定,如下所示:
fn compare(str_one: String, str_two: String, match_type: MatchType) -> bool {
match match_type {
float_match @ (MatchType::Exact | MatchType::Lower | MatchType::Greater) => {
let f_one = str_one.parse::<f64>();
let f_two = str_two.parse::<f64>();
if let (Ok(f_one), Ok(f_two)) = (f_one, f_two) {
match float_match {
MatchType::Exact => f_one == f_two,
MatchType::Lower => f_one < f_two,
MatchType::Greater => f_one > f_two,
// --- Non-exhaustive error here ---
}
} else {
false
}
},
MatchType::Other => false,
}
}
但我仍然收到
non-exhaustive
错误。有什么办法处理吗?
也许您可以保留样板
_ => false
原样,但这样就可以快捷地执行if
语句
fn compare(str_one: String, str_two: String, match_type: MatchType) -> bool {
match match_type {
MatchType::Exact | MatchType::Lower | MatchType::Greater => {
let f_one = str_one.parse::<f64>();
let f_two = str_two.parse::<f64>();
match (f_one, f_two, match_type) {
(Ok(f_one), Ok(f_two), MatchType::Exact) => f_one == f_two,
(Ok(f_one), Ok(f_two), MatchType::Greater) => f_one > f_two,
(Ok(f_one), Ok(f_two), MatchType::Lower) => f_one < f_two,
_ => false
}
},
MatchType::Other => false,
}
}
这是不可能的。然而,这种模式(与另一个
match
内的部分值匹配)相当常见。通常我会在不可能的变体上感到恐慌(unreachable!()
),但返回默认值也很好。
有模式类型作为该领域的实验性工作,可能会在未来的某个地方产生一些东西,但仍处于规划阶段。