ScalaのOptionってなんやねん

ごあいさつ

こんにちは。meviyのGrowthチームで開発している林です。 もともとJava/Kotlinを利用して開発しているところからScalaを利用した開発に飛び込んでまずハマったOption型について話してみようかと思います。

Option型とは

そもそもOption型ってなんなんでしょうか? Wikipediaによると以下のようなものです。

 プログラミング言語型理論において、Option型(英語: Option type)またはMaybe型(英語: Maybe type)は存在しない可能性のある値をカプセル化して表す多相型である。

結果が返ってくるかわからない、使うときに中身空かもしれないよーってことですね。 シュレディンガーの猫みたいな性質してやがります… この概念がなかなか理解できず入社当初は苦労した記憶があります。

(一応JavaにもOptional型というのがあるんですが、利用したことありませんでした。)

SomeとNone

Option型にはふたつのサブクラスが存在します。

  • Some

    • 値があることを指す型。
  • None

    • 値がないことを指す型。

使い方

DBから値を取得する場合などによく利用されます。

val hoge: Option[String] = hogeRepository.find(id)
// idが存在すればなにかしらの値を取得する なければNoneになる

このままだと値があるかわからないのでここから中身を取り出す必要があります。 取り出し方について、いくつか紹介します。

getを利用する

一番簡単なのはgetを利用する方法です。

val fuga = hoge.get
// hogeがSome("hoge")の場合 => fuga="hoge"
// hogeがNoneの場合 => getできずにエラー

簡単ですね。 しかし、hogeがNoneだった場合は中身がないよ!と怒られます。 Noneの場合も考慮して取得する必要がありますね。 そんな場合はgetOrElseを使いましょう!

val fuga: String = hoge.getOrElse("hogehoge")
// hogeがSome("hoge")の場合 => fuga="hoge"
// hogeがNoneの場合 => fuga="hogehoge"

中身がなかった場合にどうするかを設定できます。 ここは値をいれるだけでなくエラーを投げたりも可能です。

val fuga: String = hoge.getOrElse(throw new HogeException())
// hogeがSome("hoge")の場合 => fuga="hoge"
// hogeがNoneの場合 => HogeException()をthrowする

パターンマッチを利用する

パターンマッチを利用することでも値を取り出すことができます。

val fuga: String = hoge match {
    case Some(s) => s       // 値があれば値を取得
    case None => "hogehoge" // なければhogehogeを取得
}

単純に値を取得したいような場合にはあまり用いられませんが、値によって場合分けしたい場合などはこちらを使うことが多いですね。

val fuga: String = hoge match {
    case Some(s) if s == "fuga" => "fugafuga" // hogeの中身がfugaならfugafugaを取得
    case Some(s) => s                         // hogeの値があれば値を取得
    case None => "hogehoge"                   // 値がなければhogehogeを取得
}

ちなみにここでNoneのパターンを書かないとコンパイル時に怒られるので、ぬるぽのような実行時エラーは起こらない仕組みになってます。

パターンマッチについては以下の記事でも扱っているのでぜひご覧ください!

techblog.dt-dynamics.com

まとめ

ScalaのOption型についてざっくりと紹介してみました。 Option型は慣れてくると非常に便利で使いやすい型かと思います。 ぬるぽからも解放されるのでぜひ利用してみてください。

終わりに

本ブログではDTダイナミクスで用いている技術やプロダクト、組織について発信しています。 興味を持っていただけたらぜひカジュアル面談からよろしくお願いします!

www.wantedly.com