Rust 2018是否支持“ if let”链接?

时间:2018-11-10 02:17:56

标签: rust

我正在解析标记的向量,每个标记都是枚举类型。这意味着我得到了很多像这样的代码:

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 /问题,而该功能尚未实现。无论哪种方式,我都希望了解一些有关此功能的信息。

3 个答案:

答案 0 :(得分:9)

RFC #2497具有not been implemented yetGitHub 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);
    }
};