LoginSignup
103
77

More than 5 years have passed since last update.

[Scala]Option型から値を取り出すあれこれまとめ

Last updated at Posted at 2014-11-06

[Scala]Option型から値を取り出すあれこれまとめ

下記の変数がセットされていると仮定します

前提:
val haveFoo: Option[String] = Option("foo")
val haveNothing: Option[String] = None

1. get, getOrElse

最も単純なもの。

.getは、Noneに対して行ってしまうとエラーになり止まってしまうので、
基本的に「.get」は使わず、「.getOrElse」を使用します。

haveFoo.get // "foo"
haveFoo.getOrElse("bar") // Option("foo")

haveNothing.get // Exception
haveNothing.getOrElse("bar") // "bar"

2. match ~ case ~

可読性が高い

色んなところで多用されます

haveFoo match {
    case Some(x) => println(x)          // ここに来る x = "foo"
    case None => println("Noneです")    // ここにはこない
}

haveNothing match {
    case Some(x) => println(x)         // ここにはこない
    case None => println("Noneです")   // ここに来る。Noneの時の処理を書く
}

取り出した値を変数に入れることも可能

val message1: String = haveFoo match {
    case Some(x) => x + "が入っています"
    case None => "何も入っていません"
}
println(message1) // "fooが入っています"

val message2: String = haveNothing match {
    case Some(x) => x + "が入っています"
    case None => "何も入っていません"
}
println(message2) // "何も入っていません"

3. foreach ~

Some( )の時だけ処理をしたいときに使用します。

var count: Int = 0
haveFoo.foreach { x => // x = "foo"
    count + 1
}
println(count) // 1

haveNothing.foreach { x => // 何も処理されない
    count + 1
}
println(count) // 1 

4. for~

Option型がネストされていて、その中身に対して処理をしたい時など。

val nestedFooBar: Option[Option[String]] = Option(haveFoo)
for{
    haveFoo <- nestedFooBar
    text    <- haveFoo
} {
    println(haveFoo) //Some("foo")
    println(text)    // "foo"
}

val nestedNone: Option[Option[String]] = Option(haveNothing)
for{
    haveNothing <- nestedNone
    text        <- haveNothing
} {
    println(haveFoo)  // 何も出力されない
    println(text)     // 何も出力されない
}

5. for ~ yield ~

forの結果を返したい時。(forだけだと戻り値がUnit型なので何も返せない)

Option型がネストされている時に重宝します。

val message1: Option[String] = for(text <- haveFoo) yield text
println(message1) // Some("foo")

val message2: Option[String] = for(text <- haveNothing) yield text
println(message2) // 何も出力されない

ネスト版


val nestedFooBar: Option[ Option[String]] = Option(haveFoo)
val message1: String = (for{
    haveFoo <- nestedFooBar
    text    <- haveFoo
} yield {
    text
}).getOrElse("なにも入っていません")

println(message1) // "foo"

val nestedNone: Option[ Option[String]] = Option(haveNothing)
val message2: String = (for{
    haveNothing <- nestedNone
    text        <- haveNothing
} yield {
    text
}).getOrElse("なにも入っていません")

println(message2) // "なにも入っていません"

とりあえず、簡単なところをまとめました。

コンソールなどで試していただければ
すぐに結果が見れると思います。

Scalaを書く中で、少しでも参考になれば幸いです。

103
77
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
103
77