LoginSignup
1
0

More than 3 years have passed since last update.

Option型の変数で中身があるとき(Some)のみ特定の処理を実行したい

Last updated at Posted at 2019-10-15

問題

Option型の変数に対して中身があるとき(= Someであるとき)のみ特定の処理をしたい場合どう書きますか?

val nameOption: Option[String] = Some("bob")

// nameOptionの中身があるならそれをprintlnしたい

解法

for文または foreach メソッドを使いましょう。

for (name <- nameOption) // for文のパターン
  println(name)

nameOption.foreach { name => println(name) } // foreachメソッドのパターン
nameOption.foreach(println) // 省略してこう書いてもOK

解説

問題で書いた処理を実現したいとき、Scalaビギナーが以下のようなコードが書くのをよく目にします。

if (nameOption.nonEmpty)
  println(nameOption.get)
nameOption match {
  case Some(name) => println(name)
  case None       => ()
}

しかし、これらのコードはどちらも問題があります。
前者は危険な可能性のあるgetを使っており1、後者は何も処理をしないNoneのケースをわざわざ書いてやる必要があります。

実際には件の処理は foreach メソッドとしてデフォルトで実装されています。

scala/Option.scala at v2.13.1 · scala/scala

  /** Apply the given procedure $f to the option's value,
   *  if it is nonempty. Otherwise, do nothing.
   *
   * This is equivalent to:
   * {{{
   * option match {
   *   case Some(x) => f(x)
   *   case None    => ()
   * }
   * }}}
   *  @param  f   the procedure to apply.
   *  @see map
   *  @see flatMap
   */
  @inline final def foreach[U](f: A => U): Unit = {
    if (!isEmpty) f(this.get)
  }

備考

Scalaのfor文は単に foreach メソッドの糖衣構文であるため foreach メソッドが定義されていれば foreach メソッド呼び出しと同様に使用できます。

6.19 For Comprehensions and For Loops | Expressions | Scala 2.13

参考


  1. getは変数がNoneの場合例外が発生します。もちろん上のコードではその直前でNoneでないことをチェックしていますが、チェックしてから実際に使用するまでの間にコードが挟まったり並列実行などで元の変数が書き換えられる可能性を考えると例外が発生する可能性は否めません 

1
0
0

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
1
0