y))は、型の分解とともに使うことになるだろう。階層的なパターンの一部分を、それぞれ、定数との比較、型に依らない分解結果の変数での受け取り、単に無視(任意のパターンを受け入れ、変数にも受ける必要がない)に使う。分かりやすい例は式の簡約化だろう。「1を掛けても元と変わらない」「0を足しても元と変わらない」「0には何を掛けても0」といったルールをリスト8のように書ける。定数パターン、varパターン、ワイルドカードを使った式の簡約化の例パターンマッチングの用途これまでの説明でも出てきているが、パターンマッチングには「型による分岐」という側面と、「型の分解」という側面がある。前述の通り、パターンマッチングのような「型を調べて分岐」という機能は、オブジェクト指向言語の感覚には合わない面もある。「ダウンキャストは悪手」「型を調べたら負け」という感覚の開発者もいることだろう。一般に、型に応じて処理を変えたい場合、オブジェクト指向言語では仮想関数を使う。サンプルとして提示した「式」を表すNodeクラスに、変数の値を与えた結果を計算するCalculateメソッドを追加してみよう。仮想関数での実装ではリスト9、パターンマッチングを使った実装ではリスト10に示すようなコードになる。省略している部分は、リスト3を参照してほしい(Calculateメソッドに渡した引数は、メソッド呼び出しが連鎖する中でVarクラスのインスタンスではその値が戻り値となり、他のクラスでは無視されるようになっている。Var).Calculate(1)呼び出しは、結果として「1+1」を計算する)。パターンマッチングでのCaluculateメソッドの実装それぞれに利点があり、どちらがいいかは「状況による」ということになる。その説明のためにこれら二者の特徴について説明していこう。それぞれの特徴を表3に示す。型の中に閉じていてよく、型だけを見た単純な分岐しかしない場合、仮想関数を使う方が実行性能面でも保守しやすさの面でもいいだろう。先ほどのCalculateメソッドの例はこの条件を満たしているため、筆者の意見としては、仮想関数を使ったリスト9の書き方がよいと考える。逆に、パターンマッチングの方が好ましいと思う例を挙げていこう。1つは、型の外に実装を書く方が好ましい場合だ。サンプルとして挙げているNodeクラスは、いわばモデル(=アプリの種類によらず共通して使えるロジック)に当たる型である。結果として、特定の種類のアプリでしか使わないような機能を書く場所としては不適切となる。式を文字列化する際、アプリによって望む形式が異なるだろう。この場合はNodeクラスの中よりも、特定の形式を使いたいアプリ側のどこかに実装があった方が好ましい。型の中に書けないとなると、パターンマッチングの出番となる。一例として、MathML形式で文字列化するコードをリスト11に示す。型の中に実装を持ちたくない場合はパターンマッチングの出番となる。1つは、条件が複雑な場合だ。リスト8でも挙げたような「式の簡約化」がいい例だろう。リスト8の完全版という位置付けになるが、式の簡約化はリスト12のように書ける。条件がこのくらい複雑になると、仮想関数的な発想で分岐を書くのは困難だろう。型の分解パターンマッチングのもう1つの側面は型の分解である。この用途に限って言うと、is演算子やswitchステートメント/式のような条件分岐は必要ない場合もある。型はコンパイル時点で分かっていて、単に位置指定パターンやプロパティパターンを使ったメンバーの抽出だけを行いたい場合だ。この場合、常に条件を満たすことが分かっているのにわざわざis演算子を使うのも煩雑すぎるだろう。そこで、パターンマッチングと合わせて、型の分解用にletステートメントというものが導入される。letステートメントの最大の用途は前回説明したタプル型の分解になるだろう。いうタプル型)の結果を、リスト13に示す。letステートメントを使ったタプル型の分解letキーワードの直後には、「パターンの種類」で説明した各種パターンを書ける。パターンに合致しているかどうかはコンパイル時に確認され、合致していなければコンパイルエラーとなる。【補足】クエリ式のlet句と読み取り専用なローカル変数ちなみに、letキーワードはクエリ式のlet句ですでに使われているキーワードだ。このクエリ式のlet句も、ここで説明したletステートメントに合わせて、パターンを受け付けられるように拡張する提案も出ている。一方で、現在のlet句は、クエリ式中で使える変数を導入する構文で、通常の代入ステートメントに近い。代入ステートメントと違って、let句で導入した変数は書き換えられない(読み取り専用)。letステートメントも、リスト14に示すように、この挙動に合うようにする予定である。letステートメントによる読み取り専用なローカル変数の導入C#では、ローカル変数を読み取り専用にできるようにしてほしいという要望はずっとあった。10)なども検討されたが、最終的には、let句との一貫性や、パターンを使った分解との兼ね合いで、リスト14の構文を使うことになりそうである。まとめ今回はパターンマッチングの構文と用途について説明した。パターンマッチングはいわゆる関数型言語でよく見られる構文で、オブジェクト指向言語ではこれまであまり見られなかった。いってオブジェクト指向言語になじまないわけでも、パターンマッチングの方が新しく一方的に優れた構文というわけでもなく、既存の構文と使い分けていくことになるだろう。パターンマッチングでは以下のようなことができる。構築(コンストラクターやオブジェクト初期化子)の逆操作ができる次回は、パターンがどう評価されるかといった実装寄りの話や、複合型(クラスや構造体)以外(配列やタプル型など)に対するパターンなどについて説明する予定である。1.0がプレビュー版だった頃からC#によるプログラミング入門を公開していて、C#とともに今年で15年になる。最近の自己紹介は「C#でググれ」。※以下では、本稿の前後を合わせて5回分(第1回~第5回)のみ表示しています。INDEX]を参照してください。日本を代表する「C#(でぐぐれ)」の人、岩永信之氏によるコラムが遂に登場。今回はオープンソースで開発が行われているC#と開発者の関わり方について。7」についての議論が進んでいる。その中で提案されている「式」に関する新機能を取り上げる。複数データをまとめるための言語機能、タプル型メソッドが複数の値を戻す場合など、複数のデータを緩くまとめて、扱いたい場合はよくある。C#の次バージョンではこれを簡潔に記述するための機構として「タプル型」が導入される。型に応じた分岐や型の分解機能、パターンマッチングオブジェクトの型を階層的に調べて分岐処理を行いたい場合がある。そのための機能として、C#の次バージョンでは「パターンマッチング」が追加される。パターンマッチングの内部的な仕組みC#の次バージョンに追加される「パターンマッチング」の挙動(パターンマッチングがどう展開されるのかや、その実現方法)について説明する。機械学習エンジニアを目指す人~初中級者のための技術情報サイトです。「機械学習&AI」「クラウド&ビッグデータ」「IoTデバイス」のネット記事情報を共有中。開発者のためのSlackチーム、作りました:「機械学習&AI」「クラウド&ビッグデータ」「IoTデバイス」のネット記事情報を共有中。2020最適なビューへの切り替えを推奨します:スマートフォン用表示に。