セミコロン完全マスター

 セミコロン完全マスター

セミコロンに関する蘊蓄です

Ba655e3712aaabfbca289fe136f85fe4?s=128

Masaki Hara

March 12, 2019
Tweet

Transcript

  1. 8.

    2019/3/12 8 セミコロン完全マスター なぜセミコロン終端? 終端記号が必須 Rust, C, C++, Java, C#,

    Perl, Prolog 改行終端が可能 Ruby, Python, JavaScript, Go, Swift, Haskell, VB 終端が不要 OCaml 括弧 Scheme
  2. 11.

    2019/3/12 11 セミコロン完全マスター 暗黙のreturn { let x = 42; println!("{}",

    x); x; } 文 文 文 最後の値を使うかどうかが明確なので、 人間にもコンパイラにも優しいと考えられている
  3. 13.

    2019/3/12 13 セミコロン完全マスター Pythonの改行の扱い • 字句解析のシンプルなルールで記述されている • 原則として改行 = 文終端

    • 括弧の中では改行を無視 • 文末がバックスペースなら 続く改行を無視 ……しかし、Pythonは文と式が交互にネストしない という特殊事情がある
  4. 15.

    2019/3/12 15 セミコロン完全マスター Haskellの改行の扱い • 基本は字句解析の仕事だが、 部分的に構文エラーで駆動(Haskell 2010, §2.7) •

    インデントが同じだったら セミコロンを挿入する • 構文エラーで必要に応じて } を挿入する
  5. 18.

    2019/3/12 18 セミコロン完全マスター アイテム類とは extern crate, mod, use, impl, trait,

    type, struct, enum, static, const, fn const, type, fn 真正なアイテム ルートや mod 内に書ける トレイトアイテム trait {} 内に書ける const, type, fn 実装アイテム impl {} 内に書ける static, type, fn 外部アイテム extern {} 内に書ける など
  6. 21.

    2019/3/12 21 セミコロン完全マスター アイテム類の終端記号 ; OR 排他規則…の例外? {} use serde::{Deserialize,

    Serialize}; use serde::*; } はuse構文自体に由来するものではない 引数の一部としてたまたま出てきただけ ……と解釈されている
  7. 23.

    2019/3/12 23 セミコロン完全マスター 復習: 暗黙のreturn { let x = 42;

    println!("{}", x); x } 文 文 式 (戻り値) セミコロン終端 = その値を使わない という解釈 ブロック末尾以外はセミコロンが来ない??
  8. 24.

    2019/3/12 24 セミコロン完全マスター 文終端の原則 文は原則としてセミコロンで終端する。 しかし…… ➢ 暗黙のreturn のためには最終文のセミコロンの省略が必須。 文は式文なら何でもよい。

    ➢ {} OR ; 排他規則 のために文のセミコロンの省略が可能。 文は特定のブロック式である必要がある。 型は () である必要がある。
  9. 25.

    2019/3/12 25 セミコロン完全マスター 末尾以外のセミコロン省略 if true { 42; } else

    { 53; }; println!("Hello!"); どちらか片方は残す必要がある。 セミコロンがなければ 型がついてしまうからだ。
  10. 26.

    2019/3/12 26 セミコロン完全マスター 接頭辞禁止規則 x = if true { 42

    } else { 53 } println!("Hello!"); ここで区切っても if文にはならない
  11. 27.

    2019/3/12 27 セミコロン完全マスター セミコロン省略規則の罠 if true { 42 } else

    { 53 } - 1; println!("Hello!"); これはコンパイルが通らない。 中置・前置演算子を式文として使うことは ほぼないので、気にすることはあまりない
  12. 28.

    2019/3/12 28 セミコロン完全マスター マクロとセミコロン マクロ呼び出しの構文は文脈によって微妙に異なる アイテム類マクロ 文マクロ 式類マクロ foo!(); foo![];

    foo!{} foo!(); foo![]; foo!{}; foo!() foo![] foo!{} foo!{} セミコロンあり セミコロンなし foo! ident (); foo! ident []; foo! ident {} マクロ定義用構文 ※ () と [] は完全互換
  13. 29.

    2019/3/12 29 セミコロン完全マスター アイテム類マクロ macro_rules! foo { ($x:ident) => {

    fn $x() {} } } foo!(f1); foo![f2]; foo! { f3 } {} OR ; 排他規則で説明できる
  14. 30.

    2019/3/12 30 セミコロン完全マスター 式類マクロ macro_rules! foo { () => {

    42 } } (foo!()); (foo![]); (foo!{}); セミコロンをつけないので 全部同じ
  15. 32.

    2019/3/12 32 セミコロン完全マスター 文マクロの展開規則 fn main() { dbg! { 42

    } // Bad! dbg! { 42 }; // Good! dbg!(42); // Good! } セミコロンがついたときは、 展開後の文リストの最後の文に セミコロンを付加する ※RustのマクロはASTの構造に沿って行われるので、 「セミコロンを付加する」というのは特例的な操作になる
  16. 33.

    2019/3/12 33 セミコロン完全マスター まとめと宣伝 セミコロンひとつとっても色々な設計判断が見える • {} OR ; 排他規則

    • 暗黙のreturnのための規則 • 文マクロと式マクロが整合するための規則 • etc...