Java.use(better); Episode#21 ファインダーを作成する
┃余録:match 式とポリモフィズム
□ パターンマッチングと case class
switch 文は、構造化プログラミングにおける制御構造「選択」を支援しますが、match 式は、オブジェクト指向プログラミングにおける「ポリモフィズム」を支援するとともに、パターンマッチングの恩恵に浴する case を利用できます。
9: object Example {
13: def doIt() {
14: val c = new NamedColor("Aquamarine", 0x70, 0xDB, 0x93)
15: c match {
16: case NamedColor(n,r,g,b) =>
17: println("%s(%d,%d,%d)" format (n,r,g,b))
18: }
19: }
20: }
[14]クラス NamedColor は、名前付きの色情報を扱いますが、パターンマッチングを利用すると、コードが簡潔で見通しも良くなります。[16]case に続くコンストラクターパターン NamedColor(n,r,g,b) を利用すると、名前や色情報の取扱いが容易になります。さもなければ、次のようにコードが冗長になるので、バグの温床にもなりかねません。
: println("%s(%d,%d,%d)" format (c.name, c.red, c.green, c.blue))
パターンマッチングと密接な関係にあるのが case class です。
23: case class NamedColor(
24: name: String, red: Int, green: Int, blue: Int)
[23-24]case class を利用すると、getter/setter メソッドを用意する手間が省けるので、複雑になりがちなコードを簡潔に表現できます。
□ def unapply
スライサーを使えば、キャベツの千切りも楽ですが、プロの料理人を目指すなら、それに頼らない包丁さばきも身につけたいものです。同様に「プロ」グラマーの嗜みとして、case class に頼らないコードも記述できるようになりたいものです。これと同等のものは、object/class の組み合わせで実現できます。
27: object NamedColor { 28: def unapply(x: NamedColor): Option[(String,Int,Int,Int)] = 29: Some((x.name, x.red, x.green, x.blue)) 30: } 31: 32: class NamedColor( 33: name0: String, red0: Int, green0: Int, blue0: Int) { 34: def name = name0 35: def red = red0 36: def green = green0 37: def blue = blue0 38: }
[28-29]メソッド unapply では、コンストラクターパターンの動作を規定します。リターン値に指定したタプルの各要素が、コンストラクターパターンの各引数に対応します。これに伴って[32-38]クラス NamedColor では、インスタンス属性を参照するためのメソッド群を用意します。
すると、コンストラクターパターンを介して、名前や色情報を個別に参照できるので、コードが簡潔で見通しが良くなります。確かに、case class は便利ですが、痒い所に手が届かないときには、object/class が必要になります。
》作業中です《
↑ TOP