基本的なパターンマッチとScalaで重要な“関数”スケーラブルで関数型でオブジェクト指向なScala入門(4)(1/3 ページ)

Scalaの特徴を紹介し、基本構文や関数、クラスなど、Scalaの基本的な機能について解説する入門連載

» 2012年04月05日 00時00分 公開
[中村修太クラスメソッド株式会社]

前回のおさらいと今回の内容

 前回の記事「Scalaの基本的なコレクション4タイプと制御構文・例外」では、Scalaのコレクションクラスの基本的な使い方、条件分岐や繰り返しなどの制御構文やScalaで例外を扱う方法を紹介しました。

 今回は、まず前回紹介しきれなかった「パターンマッチ」から紹介し、次にScalaの重要な機能である「関数」を紹介します。

 第1回記事では、Scala標準のREPLScala 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(関数型言語)をうまく使えるようになるポイントになると思います。次ページからは、関数の概要からさまざまな関数の使い方を紹介します。

       1|2|3 次のページへ

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。