Option型の利用
Option型は非常に便利な型ですのでここで紹介します。
Optionは、値が存在する場合としない場合の2通りの状態を表すコンテナです。
Optionはcaseクラスです。Option型には、サブタイプとして値が存在する場合のSomeと、値がない場合のNoneがあります。
どのように利用すべきか、例をもとに説明します。
Javaでは、java.util.Mapクラスのget( Object key )メソッドは、要素がない場合はnullを返しました。
scala> val jmap = new java.util.HashMap[String,String]
jmap: java.util.HashMap[String,String] = {}
scala> jmap.put( "A", "a" )
res1: String = null
scala> jmap.put( "B", null )
res2: String = null
scala> jmap.get( "A" )
res3: String = a
scala> jmap.get( "B" )
res4: String = null
scala> jmap.get( "C" )
res5: String = null
nullが返された場合、Mapの中に、keyに対応する値がnullに設定されているのか、それともkeyに対応する要素が存在しないのでnullなのか判断がつきません。上記の例では、keyを「B」でgetを呼び出した場合は前者で「C」で呼び出した場合は後者です。
Scalaで用意されているMapクラスのget関数はOption型を返します。keyに対して値が存在する場合はSome(値)でない場合はNoneです。
scala> val map = Map( "A" -> "a" , "B" -> null ) map: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map((A,a), (B,null)) scala> map.get( "A" ) res1: Option[java.lang.String] = Some(a) scala> map.get( "B" ) res2: Option[java.lang.String] = Some(null) scala> map.get( "C" ) res3: Option[java.lang.String] = None
このように、keyが存在する場合はSomeが返り、ない場合はNoneが返るので、JavaのMap型のような問題はありません。
また、Option型はcaseクラスです。前回、caseクラスについて簡単に説明しましたが、caseクラスとパターンマッチを利用して条件判断をさせることができます。
scala> map.get("A") match {
| case Some(v) => println("値は%sです。" format v )
| case None => println("値はありません。" )
| }
値はaです。
scala> map.get("C") match {
| case None => Some(v) => println("値は%sです。" format v )
| case None => println("値はありません。")
| }
値はありません。
また、Option型には、filter関数やmap関数が用意されいています。さらに、Option型がSomeだったら値を取り出し、Noneだったらデフォルト値を返すgetOrElseという関数が用意されています。
これらを組み合わせて、mapから文字列を取り出して文字数を数える処理は、このように書くことができます。
scala> val m = Map( "a" -> "foo" , "b" -> "baaaaaar" )
m: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map((a,foo), (b,baaaaaar))
scala> m.get( "a" ).map{ _.length }.getOrElse( -1 )
res1: Int = 3
scala> m.get( "c" ).map{ _.length }.getOrElse( -1 )
res2: Int = -1
このように、Mapの中にkeyに対応する値がある場合は文字数を、ない場合は-1を返す処理を、if文を用いずに書くことができました。
JavaのMapを利用してこのような処理をする場合は、getメソッドで返される値がnullであるか、if文でnullチェックをする必要があるでしょう。nullチェックは、ともすれば書くのを忘れてしまい、思わぬNullPointerExceptionが発生する原因となります。
ScalaでOption型を利用することによって、このようにnullチェック忘れでNullPointerExceptionが発生するようなケアレスミスを駆逐することができます。
まとめ
今回は、Scalaが持つ関数型言語しての側面を解説しました。
関数をオブジェクトとして取り扱うことで、手続き型のプログラミングモデルとは異なった柔軟なプログラミングが可能になります。
次回Scalaでのクラスやトレイトの使い方、パターンマッチの詳細について、踏み込んだ解説をする予定です。
参考資料
- The Scala Programing Language
- 『Programming in Scala』 Martin Odersky・Lex Spoon・Bill Venners 著、Artima Inc、2008年11月
- 『Scalaスケーラブルプログラミング』 Martin Odersky・Lex Spoon・Bill Venners 著、羽生田栄一 監修、長尾 高弘 訳、インプレスジャパン、2009年8月
- 『Scalaプログラミング入門』 David Pollak 著、大塚庸史 訳、羽生田栄一解説、日経BP社、2010年3月
- Welcome to Scala hack-a-thon #1’s documentation!
この記事は参考になりましたか?
既に会員の方はを行ってください。
- 今からでも遅くない これから始めるScala連載記事一覧
-
- 今からでも遅くない これから始めるScala(後編)
- 今からでも遅くない これから始めるScala(中編)
- 今からでも遅くない これから始めるScala(前編)
- この記事の著者
-
山田 祥寛(ヤマダ ヨシヒロ)
静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
-
WINGSプロジェクト 尾崎 智仁(オザキ トモヒト)
<WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書、記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
