Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
74
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

@kichiemon

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

[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を書く中で、少しでも参考になれば幸いです。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
74
Help us understand the problem. What are the problem?