Поддерживает ли Rust 2018 цепочку «если позволено»? - PullRequest
0 голосов
/ 10 ноября 2018

Я анализирую вектор токенов, каждого типа enum.Это означает, что я получаю много кода вроде:

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 для объединения этих условий и битов "если позволено" в том, что чувствует себя намного более эргономичным - Отслеживание проблемы для eRFC 2497 "if- и while-let-Цепи занимают 2 " и Поддержка &&, если позволяют выражения - это позволило бы мне написать что-то вроде:

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);
}

Однако я не могу получить этоскомпилируйте в моей копии ночной Rust с edition="2018" (точная версия 1.32.0-nightly (653da4fd0 2018-11-08)).Так что либо у меня неправильный синтаксис, либо я неверно истолковал RFC / проблемы, и эта функция еще не реализована.В любом случае, я хотел бы получить некоторую информацию о том, как эта функция стоит.

Ответы [ 2 ]

0 голосов
/ 12 ноября 2018

Несмотря на то, что Хеллоу прав, что RFC # 2497 еще не поддерживается в 2018 году (и в 2015 году), я чувствовал, что библиотека if_chain, упомянутая Михаилом, заслуживает ответа.

Библиотека if_chain предоставляет макрос, который преобразует некоторый код, почти в форме RFC # 2497, в действительный Rust.

Вы можете написать:

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);
    }
};

который компилятор обрабатывает как:

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);
            }
        }
    }
}
0 голосов
/ 10 ноября 2018

RFC # 2497 еще не реализовано . Проблема GitHub, которую вы связали , предназначена только для описания того, как справляется с неоднозначностью .

Чтобы включить вторую интерпретацию в предыдущем разделе, в 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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...