基本的なパターンマッチとScalaで重要な“関数”:スケーラブルで関数型でオブジェクト指向なScala入門(4)(1/3 ページ)
Scalaの特徴を紹介し、基本構文や関数、クラスなど、Scalaの基本的な機能について解説する入門連載
前回のおさらいと今回の内容
前回の記事「Scalaの基本的なコレクション4タイプと制御構文・例外」では、Scalaのコレクションクラスの基本的な使い方、条件分岐や繰り返しなどの制御構文やScalaで例外を扱う方法を紹介しました。
今回は、まず前回紹介しきれなかった「パターンマッチ」から紹介し、次にScalaの重要な機能である「関数」を紹介します。
第1回記事では、Scala標準のREPLとScala IDEで動作を確認してみました。今後本記事のサンプルコードは、どちらで確認しても問題はありませんが、対話的に実行でき、1文ごとにコードの結果が分かって便利なので、基本的にはREPLを用いて説明していきます。
Scala IDEを使用する場合、第1回記事の『Scala IDE for Eclipseで「Hello Scala!」』を参照してプロジェクトを作成して実行してください。REPLを使用する場合は、コンソール上でscalaコマンドを実行し、REPLを起動してください。
複数の選択肢から1つを選ばせる「パターンマッチ」
Scalaでは、「match」構文を使用すると、Javaの「switch-case」文のように複数の選択肢から1つを選ばせる処理を記述できます。このmatch構文は非常に強力で、単純な値のマッチングだけではなく、クラスやコレクションなど、さまざまなものを選択肢にできます。
今回は、パターンマッチの中でも基本的なマッチングを紹介します。構文は、以下のようになっています。
x match { case [選択肢1] => [xが選択肢1にmatchしたときの処理] case [選択肢2] => [xが選択肢2にmatchしたときの処理] case _ => [xが選択肢にmatchしなかったときの処理] }
「x」が比較したい値で、「case」文を記述して処理を分岐しています。caseに記述する選択肢は、値や型を指定できます。またJavaと違い、「break」を記述しなくても、次のcase文に処理が行くことはありません。
最後のcase文に記述している「_」は、ほかのcase文に一致しなかった場合に処理される選択肢です。Javaのswitch-case文でいう、「default」に相当します。
なお、「_」選択肢は記述しなくても構いません。記述しないで何も一致しなかった場合、「MatchError」が発生します。
シンプルなマッチング
実際に、matchを使用してみましょう。以下の例は変数xの値によって処理を分岐させています。
scala> val x = 10 x: Int = 10 scala> x match { | case 1 => println("x is 1") | case 10 => println("x is 10") | case _ => println("x is other number") | } x is 10
xの値が「10」なので、「case 10」の処理内容が実行されています。
次は選択肢に型を指定してみましょう。例はxの実際の型に応じて処理を分岐しています。
scala> val x:Any = "hello" x: Any = hello scala> val res = x match { | case i:Int => println("x = " + i.toString); 1 | case s:String => println("x = " + s); 2 | case _ => println("other"); 3 | } String res: Int = 2
case部分には「変数名:型名」という形式でmatchさせる内容を記述しています。xで指定している型の「Any」とは、Scalaのすべての親クラスであり、その型の内容に応じて処理を分岐しています。
ifやforと同じように、matchも値を返すことが可能で、例のcase文では、「println」で文字列を表示した後、それぞれ数値を返しています。
パターンガード
もう少し複雑な選択肢条件を指定したい場合、「パターンガード」というif文を使用できます。これは、case文の「=>」の前に指定するif文で、任意の論理式を記述します。この式が「true」にならないと、マッチしたことにはなりません。
例ではxがInt型かつ100以上の場合に処理するようにしています。
scala> val x:Any = 50 x: Any = 50 scala> val res = x match { | case i:Int if i >= 100 => println("i > 100") | case _ => println("other") | } other
xは値が50なので一致せず、「_」の処理が実行されます。xを100以上にして、もう一度実行すると、最初のcase文がマッチします。
今回は基本的なパターンマッチのみ使用しましたが、Scalaではこれら以外にさまざまな種類のパターンが存在します。そういったパターンは、今後の連載で紹介します。
“関数型言語”でもあるScalaの“関数”
Scalaにおける「関数」は、とても重要な機能です。第1回の記事で、「Scalaでは関数型プログラミングが可能」と説明しました。
関数型プログラミングとは、Scalaが関数を「ファーストクラスオブジェクト」として扱える(関数を引数や戻り値にできる)ことを利用し、副作用を持たない関数を使用してプログラムを構築する手法です。
関数をうまく使うことが、Scala(関数型言語)をうまく使えるようになるポイントになると思います。次ページからは、関数の概要からさまざまな関数の使い方を紹介します。
Copyright © ITmedia, Inc. All Rights Reserved.