代码之家  ›  专栏  ›  技术社区  ›  Boiethios

这条奇怪的线是干什么的?

  •  13
  • Boiethios  · 技术社区  · 6 年前

    pull request 对rust编译器进行了新的测试。它验证了一个奇怪的行是否可以编译:

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

    这条线到底是干什么的?

    1 回复  |  直到 6 年前
        1
  •  23
  •   Lukas Kalbertodt    6 年前

    我们把它拆了!首先,我重新格式化了这一行,以稍微提高“可读性”。

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

    它开始于 let val = //<newline>; . 所以这是一个简单的let绑定表单 let val = ⟨v⟩; . 我们来讨论一下 ⟨v⟩ 做:

    • 通过 操作员: !( ⟨_⟩ )
      • 通过比较 == : ⟨lhs⟩ == ⟨rhs⟩
        • ¨lhs–_ :闭包的函数调用 ( ⟨closure⟩ )( ⟨args⟩ )
          • 关闭 :闭包定义 |⟨first_param⟩, ⟨second_param⟩| ⟨body⟩
            • ¨第一个参数 : (..): (_, _) . 此参数具有类型批注 (_, _) 意思是它是一个二元组。模式(通常,你会找到一个名字)是 (..) 意思是:一个元组,但是忽略它的所有元素。
            • 第二个参数 : __@_ . 这是通常从匹配绑定中得知的模式: name @ pattern . 所以实际情况是 _ (不绑定任何内容)并且该值通过 @ 名副其实 __ (两个下划线,这是一种有效的标识符)。
            • “身体” : 小精灵 . 这只是我们将第二个参数绑定到的标识符。所以闭包基本上等于 |_, x| x .
          • 阿尔格斯 :具有内联注释的两个参数的列表 /**/ 介于两者之间: ⟨first_arg⟩/**/, ⟨second_arg⟩
            • 第一个参数 : (&*"\\", '@') . 这只是一个2元组,其中第一个元素是包含反斜杠的字符串,第二个元素是char '@' . 这个 &* 因为第一个元素取消了。
            • 第二次ARG : {} . 这是一个空块,其类型为 () . 所以作为第二个参数,传递一个单元。
        • 法国皇家海军 :内有一个语句的带括号块: { ⟨stmt⟩; } . 注意,这是一个带有分号的语句。这意味着不会从块返回结果。相反,块返回 () 就像空街区一样 {} .
          • STMT :索引表达式 { &⟨collection⟩[⟨index⟩] } .
            • –收藏–收藏 : [..=..] . 这是一个只有一个元素的数组。元素是 ..= .. 哪个是 RangeToInclusive 哪里 end 范围的一部分是 RangeFull 书面的 .. .
            • 指数 : . 这只是 测距仪 再一次。

    总而言之 :我们将调用闭包的结果与计算结果为 () . 关闭基本上是 ε,xx 第二个论点是 {} (评估结果为 () ,因此整个闭包调用表达式的计算结果为 () .

    这意味着整个过程相当于:

    • let val = !( () == () ); ,相当于:
    • let val = !( true ); ,相当于:
    • let val = false;
    推荐文章