14

新しいケース クラスを追加する場合、すべてのパターン マッチング コードを検索して、新しいクラスを処理する必要がある場所を見つける必要があるということですか? 私は最近この言語を学んでおり、パターン マッチングの賛否両論を読んでいるうちに、パターン マッチングをどこで使用すべきかについて混乱していました。以下を参照してください。

プロ: Odersky1Odersky2

短所: ビースト

コメントもそれぞれのケースでかなり良いです。では、パターン マッチングはわくわくするものですか、それとも使用を避けるべきものですか? 実際、「使うタイミング次第」という答えになると思いますが、ポジティブなユースケースとネガティブなユースケースは何ですか?

4

3 に答える 3

22

ジェフ、あなたの直感は正しいと思います。

仮想メソッド ディスパッチを使用したオブジェクト指向のクラス階層は、実装する必要があるメソッドのセットが比較的固定されている場合に適していますが、階層のルートから継承してそれらのメソッドを実装する潜在的なサブクラスが多数ある場合に適しています。このような設定では、新しいサブクラスを追加するのは比較的簡単ですが (すべてのメソッドを実装するだけです)、新しいメソッドを追加するのは比較的困難です (すべてのサブクラスを変更して、新しいメソッドが適切に実装されるようにする必要があります)。

パターン マッチングに基づく機能を備えたデータ型は、データ型に属するクラスのセットが比較的固定されている場合に適していますが、そのデータ型で動作する可能性のある関数が多数あります。このような設定では、データ型に新しい機能を追加するのは比較的簡単ですが (そのすべてのクラスでパターン マッチを行うだけです)、データ型の一部である新しいクラスを追加するのは比較的困難です (一致するすべての関数を変更する必要があります)。新しいクラスを適切にサポートしていることを確認するためのデータ型)。

OO アプローチの標準的な例は、GUI プログラミングです。GUI 要素がサポートする必要がある機能はほとんどありません (画面上に自分自身を描画することが最低限必要です) が、新しい GUI 要素 (ボタン、テーブル、チャート、スライダーなど) は常に追加されています。パターン マッチング アプローチの標準的な例はコンパイラです。プログラミング言語は通常、比較的固定された構文を持っているため、構文ツリーの要素が変更されることはほとんどありません (あったとしても) が、構文ツリーに対する新しい操作が常に追加されています (より高速な最適化、より徹底的な型分析など)。

幸いなことに、Scala では両方のアプローチを組み合わせることができます。ケース クラスは、パターン マッチングと仮想メソッド ディスパッチの両方をサポートできます。通常のクラスは仮想メソッドのディスパッチをサポートし、対応するコンパニオン オブジェクトでエクストラクタを定義することでパターン マッチングを行うことができます。それぞれのアプローチがいつ適切であるかを決定するのはプログラマ次第ですが、私はどちらも有用だと思います。

于 2009-02-19T09:17:52.110 に答える
16

私はセドリックを尊敬していますが、この問題に関して彼は完全に間違っています。Scala のパターン マッチングは、必要に応じてクラスの変更から完全にカプセル化できます。ケース クラスを変更するには、対応するパターン マッチング インスタンスを変更する必要があることは事実ですが、これは、そのようなクラスを単純な方法で使用する場合に限られます。

Scala のパターン マッチングは、常にクラスのコンパニオン オブジェクトのデコンストラクターに委譲します。ケース クラスを使用すると、このデコンストラクターは (コンパニオン オブジェクトのファクトリ メソッドと共に) 自動的に生成されますが、この自動生成されたバージョンをオーバーライドすることも可能です。いつでも、パターン マッチング プロセスを完全に制御できることをアサートし、クラス自体の潜在的な変更からパターンを隔離できます。したがって、パターン マッチングは、他の方法と同様に、カプセル化の安全なフィルターを介してクラス データにアクセスするもう 1 つの方法です。

したがって、特にオブジェクト指向プログラミングと設計の分野で膨大な量の研究を行ってきたことを考えると、ここでは Odersky 博士の意見が信頼できるでしょう。

どこに使うかは好み次第です。コードがより簡潔で保守しやすくなる場合は、それを使用してください。そうでなければ、しないでください。ほとんどのオブジェクト指向プログラムでは、パターン マッチングは不要です。ただし、より機能的なイディオム ( 、 など) を統合し始めるとOptionListパターン マッチングによって構文上のオーバーヘッドが大幅に削減され、型システムによって提供される安全性が向上することがわかると思います。一般に、何らかの条件を同時にテストしながらデータを抽出したい場合 (例: から値を抽出するなどSome) はいつでも、パターン マッチングが役立つ可能性があります。

于 2009-02-19T03:01:36.693 に答える
1

関数型プログラミングをしているなら、パターンマッチングは間違いなく良いです。OOの場合、良い場合もあります。セドリックの例自体では、print()メソッドを概念的にどのように表示するかによって異なります。Termそれは各オブジェクトの振る舞いですか?それともそれはそれの外にあるものですか?外にあると思いますが、パターンマッチングを行うのは理にかなっています。一方、Employeeさまざまなサブクラスを持つクラスがある場合、基本クラスのその属性(名前など)でパターンマッチングを実行することは、設計上の選択としては適切ではありません。

また、パターンマッチングは、クラスのメンバーを解凍するエレガントな方法を提供します。

于 2009-02-19T07:08:38.533 に答える