Что делает эта странная строка? - PullRequest
0 голосов
/ 06 июня 2018

A запрос на получение выполнен с новым тестом для компилятора Rust.Он проверяет, что странная строка может компилироваться:

fn main() {
    let val = !((|(..):(_,_),__@_|__)((&*"\\",'@')/**/,{})=={&[..=..][..];})//
    ;
    assert!(!val);
}

Что именно делает эта строка?

1 Ответ

0 голосов
/ 06 июня 2018

Давайте разберемся!Во-первых, я переформатировал строку, чтобы немного увеличить «читаемость».

let val = !(
    (
        |(..): (_, _), __@_| __
    )(
        (
            &*"\\", 
            '@'
        ) /**/, 
        {}
    )
    ==
    {
        &[..=..][..];
    }
)//
;

Она начинается с let val = и заканчивается //<newline>;.Таким образом, это простая привязка в форме let val = ⟨v⟩;.Давайте обсудим, что делает ⟨v⟩:

  • Отрицание с помощью оператора not : !( ⟨_⟩ )
    • Сравнение с помощью ==: ⟨lhs⟩ == ⟨rhs⟩
      • ⟨lhs⟩ : функциональный вызов замыкания ( ⟨closure⟩ )( ⟨args⟩ )
        • ⟩closure⟩ : определение замыкания |⟨first_param⟩, ⟨second_param⟩| ⟨body⟩
          • «first_param» : (..): (_, _).Этот параметр имеет аннотацию типа (_, _), означающую, что он является 2-кортежем.Шаблон (где обычно вы найдете одно имя) - (..), что означает: кортеж, но игнорируйте все его элементы.
          • ⟨second_param⟩ : __@_.Этот шаблон обычно известен из привязок совпадений: name @ pattern.Таким образом, фактическим шаблоном является _ (который ничего не связывает), и значение связывается через @ с именем __ (два подчеркивания, что является своего рода допустимым идентификатором).
          • ⟨body⟩ : __.Это просто идентификатор, к которому мы привязали второй параметр.Таким образом, закрытие в основном эквивалентно |_, x| x.
        • ⟨args⟩ : список из двух аргументов со встроенным комментарием /**/ между: ⟨first_arg⟩/**/, ⟨second_arg⟩
          • ⟨first_arg⟩ : (&*"\\", '@').Это просто 2-кортеж, где первый элемент представляет собой строку, содержащую обратную косую черту, а второй - символ '@'.&* для первого элемента отменяется.
          • condsecond_arg⟩ : {}.Это пустой блок, имеющий тип ().Таким образом, в качестве второго аргумента передается единица измерения.
      • ⟨rhs⟩ : блок скобок с одним операторомвнутри: { ⟨stmt⟩; }.Обратите внимание, что это утверждение с точкой с запятой.Это означает, что результат не возвращается из блока.Вместо этого блок возвращает () точно так же, как пустой блок {}.
        • ⟨stmt⟩ : индексное выражение { &⟨collection⟩[⟨index⟩] }.
          • «Коллекция» : [..=..].Это массив с одним элементом.Элементом является ..= .., который является RangeToInclusive, где end диапазона является RangeFull, записанным ...
          • ⟨index⟩ : ...Это просто RangeFull снова.

Итак, в итоге : мы сравниваем результатвызова закрытия для связанного блока, который оценивается как ().Закрытие в основном равно |_, x| x, а второй передаваемый ему аргумент - {} (который оценивается как ()), поэтому все выражение вызова замыкания оценивается как ().

Это означает, что все это эквивалентно:

  • let val = !( () == () );, что эквивалентно:
  • let val = !( true );, что эквивалентно:
  • let val = false;
...