またまたパターンマッチング。
それだけこの概念が大事だってことなんだろうね。
package sample.snippet /** Illustrate the use of pattern matching in Scala. */ object Patterns { /** We need an abstract base class for trees. * Subclasses with the 'case' modifier can used in pattern matching expressions * to deconstruct trees. */ abstract class Tree case class Branch(left: Tree, right: Tree) extends Tree case class Leaf(x: Int) extends Tree /** Case classes have an implicit constructor methods * which allows to create objects without the 'new' keyword. * It saves some typing and makes code clearer */ val tree1 = Branch(Branch(Leaf(1), Leaf(2)), Branch(Leaf(3), Leaf(4))) /** Return the sum of numbers found in leaves. * 'match' is a generalization of 'switch' in C-like languages. * * Patterns consist of case class constructors * (which can be nested), * and lower case variables which are bound to the values * with which the class has been constructed. */ def sumLeaves(t: Tree): Int = t match { case Branch(l, r) => sumLeaves(l) + sumLeaves(r) case Leaf(x) => x } /** This illustrates the use of Option types. * Since the method is not known in advance to find 'x', * the return type is an Option. * Options habe two possible values, either 'Some' or 'None'. * It is a type-safe way around 'null' values. */ def find[A, B](it: Iterator[(A, B)], x: A): Option[B] = { var result: Option[B] = None while (it.hasNext && result == None) { val Pair(x1, y) = it.next if (x == x1) result = Some(y) } result } def printFinds[A](xs: List[(A, String)], x: A) = { find(xs.elements, x) match { case Some(y) => println(y) case None => println("no match") } } def main(args: Array[String]) { println("sum of leafs = " + sumLeaves(tree1)) val l = List((3, "three"), (4, "four")) printFinds(l, 4) printFinds(l, 10) } }
抽象クラスTreeがあって、サブクラスBranchとLeafがある。
case修飾子をつけるとパターンマッチングで使える。
ケースクラスはコンストラクタメソッドを暗黙的に持っていて、
newキーワードを使わずにオブジェクトを生成できる。
タイピングを減らしコードをわかりやすくするため。
matchはCライクなswitchの一般化。
パターンはケースクラスのコンストラクタからなり(ネスト可)、
小文字の変数は生成するときに与えられた値である。
このサンプルではオプションタイプを使っている。
findメソッドでは'x'が見つかるとは限らないので、戻り値の型をOptionにしている。
Optionには2つの値がある。'Some'と'None'だ。
これはnullを扱うタイプセーフな方法だ。
なるほど。
もうこの辺りの概念は理解できてる。
実行結果。
sum of leafs = 10 four no match