web-dev-qa-db-ja.com

ScalaのOption [x]をxに変換する

scala(2.1)のplayを使用しており、「Option [Long]」値を「Long」に変換する必要があります。

私は反対の方法を知っています、つまり:

  def toOption[Long](value: Long): Option[Long] = if (value == null) None else Some(value)

しかし、私の場合、「Option [Long]」の値を型として「Long」を取るメソッドに渡す必要があります。助けてください。

21
mahoosh

まず、「反対」の実装には重大な問題があります。メソッドにLongという名前の型パラメーターを配置することにより、標準ライブラリーからLong型をシャドウイングしています。代わりに、おそらく次のことを意味します。

def toOption(value: Long): Option[Long] =
  if (value == null) None else Some(value)

これも一種の無意味です(scala.Longは参照型ではなく、nullになることはないため)、苦痛と混乱の原因となるJava.lang.Longを参照する場合を除きます。最後に、参照型(Stringなど)を扱っていたとしても、まったく同じである次のように書く方が良いでしょう。

def toOption(value: String): Option[String] = Option(value)

このメソッドは、Nonevalueである場合にのみ、nullを返します。

質問に対処するために、次の方法があるとします。

def foo(x: Long) = x * 2

通常、Option[Long]fooに渡すという観点から考えるのではなく、fooを介してOptionmapを「リフティング」する必要があります。

scala> val x: Option[Long] = Some(100L)
x: Option[Long] = Some(100)

scala> x map foo
res14: Option[Long] = Some(200)

Optionの重要な点は、NullPointerException- y問題のクラス全体を回避するために、「null」値の可能性を(型レベルで)モデル化することです。 mapOptionを使用すると、Optionにある可能性のある値に対して計算を実行しながら、空である可能性をモデル化することができます。

別の回答ノートとして、getOrElseを使用してOptionを「救済」することも可能ですが、これは通常Scala(デフォルト値)。

27
Travis Brown

Option [Long]としてxがある場合、x.getはLongを提供します。

44
Dao Lam

このメソッドはOption [A]で既に定義されており、getと呼ばれています:

scala> val x = Some(99L)
x: Some[Long] = Some(99)

scala> x.get
res0: Long = 99

問題は、Noneでgetを呼び出すと、NoSucheElement例外がスローされることです。

scala> None.get
Java.util.NoSuchElementException: None.get

したがって、オプションタイプを使用してもメリットは得られません。

したがって、前述のように、賢明なデフォルト値を提供するか、例外を処理できる場合は、getOrElseを使用できます。

慣用的なscala=方法はmapまたはfor-comprehensionを使用します

x map (_ + 1)
res2: Option[Long] = Some(100)

または

for (i <- x) yield i +1
res3: Option[Long] = Some(100)
7
Andreas Neumann

オプションは、副作用をローカライズする方法です(関数は空の値を返すことができます)。そして、計算をオプションに引き上げるのに適したスタイル(オプションはmapflatMapメソッド)。

val x = Option[Long](10) 
x.map { a => a + 10 }

そして、副作用を手動で処理して値を抽出します。

val res = x match {
  case Some(a) => s"Value: $a"
  case None    => "no value"
} 
2
Yuriy

オプションがNoneのときに何が起こるかを決める必要があります。デフォルト値を提供していますか?

def unroll(opt: Option[Long]): Long = opt getOrElse -1L  // -1 if undefined

unroll(None) // -> -1

例外をスローすることもできます:

def unroll(opt: Option[Long]): Long = opt.getOrElse(throw 
  new IllegalArgumentException("The option is expected to be defined at this point")
)

unroll(None) // -> exception

使用する理由が特にない限り、nullの使用は控えてください(opt.orNull)。

1
0__

既に述べたように、getOrElseは、質問に直接答える際におそらく探しているものです。

オプションに変換するには、次のこともできることに注意してください。

val myOption = Option(1)

myOptionはSome(1)になります

val myOption = Option(null)

myOptionはNoneになります。

0