我正在解析标记的向量,每个标记都是枚举类型。这意味着我得到了很多像这样的代码:
if v.len() >= 3 {
if let Token::Type1(value1) = &v[0] {
if let Token::Type2(value2) = &v[1] {
if let Token::Type(value3) = &v[2] {
return Parsed123(value1, value2, value3);
}
}
}
}
这很丑-我已经解决了,我可以做得更好一些:
if v.len() >= 3 {
if let (Token::Type1(value1), Token::Type2(value2), Token::Type3(value3)) =
(&v[0], &v[1], &v[2])
{
return Parsed123(value1, value2, value3);
}
}
但是说实话,它并没有好多少。
但是,存在一些封闭的问题/ RFC,这些条件和“ if let”位以更符合人体工程学的方式链接起来-Tracking issue for eRFC 2497 "if- and while-let-chains take 2"和Support && in if let expressions-这会让我写点东西喜欢:
if v.len() >= 3 &&
let Token::Type1(value1) = &v[0] &&
let Token::Type2(value2) = &v[1] &&
let Token::Type3(value3) = &v[2]
{
return Parsed123(value1, value2, value3);
}
但是,我似乎无法在edition="2018"
(准确的版本是1.32.0-nightly (653da4fd0 2018-11-08)
)的每晚Rust副本中编译它。因此,要么我语法错误,要么我误解了RFC /问题,而该功能尚未实现。无论哪种方式,我都希望了解一些有关此功能的信息。
答案 0 :(得分:9)
RFC #2497具有not been implemented yet。 GitHub issue you linked仅用于描述to deal with the ambiguity的方式。
要在上一节中启用第二种解释,必须在Rust 2015中发出警告,告知用户两者都会成为硬错误,在Rust版本的第一版中,该版本的2018年版本稳定,而没有[...] let_chains功能已经稳定。
所以不,您还不能使用语法,而是像以前一样使用元组作为解决方法。
if v.len() >= 3 {
if let (Token::Type1(value1), Token::Type2(value2), Token::Type3(value3)) =
(&v[0], &v[1], &v[2])
{
return Parsed123(value1, value2, value3);
}
}
答案 1 :(得分:2)
正如L.F.的评论中所述,到2020年,现在有了另一种选择。它仍然没有给我们链式if let
,但是确实允许我们在切片上进行匹配-这足以使该示例更加简洁。该代码现在可以写为
if let [Token::Type1(value1), Token::Type2(value2), Token::Type3(value3), ..] = v {
return Parsed123(value1, value2, value);
}
答案 2 :(得分:1)
虽然在2018年(和2015年)尚不支持RFC#2497是正确的,但我感到Michail提到的true && function burrito() {
return '';
}
burrito();
// VM1158:1 Uncaught ReferenceError: burrito is not defined
库值得回答。
if_chain
库提供了一个宏,该宏将几乎以RFC#2497形式出现的某些代码转换为有效的Rust。
您可以写:
if_chain
编译器将其视为:
if_chain! {
if v.len() >= 3;
if let Token::Type1(value1) = &v[0];
if let Token::Type2(value2) = &v[1];
if let Token::Type3(value3) = &v[2];
then {
return Parsed123(value1, value2, value3);
}
};