Java.use(better);
■ Scala: パターンの応用
Scala で同じことを実現すると、
val expression = Sub(Add(Const(3), Const(4)), Const(2)) println(expression.eval)
演算子 new を書く必要がないので、コードが簡潔で見通しも良くなります。
abstract class Expr { def eval(): Int = this match { case Const(value) => value case Add(left,right) => left.eval + right.eval case Sub(left,right) => left.eval - right.eval } } case class Const(value: Int) extends Expr case class Add(left: Expr, right: Expr) extends Expr case class Sub(left: Expr, right: Expr) extends Expr
抽象クラス Expr の直下に3つのケースクラス Add/Sub/Const を定義します。Java で実現したものと比較すると、いかに簡潔になるかが分ります。
□ Scala: ケースクラスの効能
ケースクラスはどれも、本体を持たない空のクラスです。が、これだけで、Java で実現すべきコードの大半を省略できます。その違いは(前述したように)同等の機能を Java で実現したものと比較すると明らかです。
case 宣言したクラスがあると、コンパイラーは、クラスと同じ名前の「ファクトリーメソッド」を用意します。すると、演算子 new を省略できるので、
new Sub(new Add(new Const(3), new Const(4)), new Const(2))
このような冗長な表現は不要になります。
クラスの名前に続いて引数並びがあると、コンパイラーは、暗黙の val 宣言をしたものと見なすので、
class Add(val left: Expr, val right: Expr) ...
このように、各引数を「フィールド」として扱えます。たとえば、
val expression = Sub(Add(Const(3), Const(4)), Const(2)) println(expression.left) println(expression.right)
これを実行すると、次の結果が得られます。
Add(Const(3),Const(4)) Const(2)
オブジェクトに固有の文字列表現が得られるように、コンパイラーは、メソッド toString を用意するので、たとえば、
val expression = Sub(Add(Const(3), Const(4)), Const(2)) println(expression)
これを実行すると、次の結果が得られます。
Sub(Add(Const(3),Const(4)),Const(2))
すると、実行したコードの断片とオブジェクトに固有の文字列表現が、一致しているのが分ります。
↑ TOP
》作業中です《update*13/02/12 20:14:40