scala(2.1)のplayを使用しており、「Option [Long]」値を「Long」に変換する必要があります。
私は反対の方法を知っています、つまり:
def toOption[Long](value: Long): Option[Long] = if (value == null) None else Some(value)
しかし、私の場合、「Option [Long]」の値を型として「Long」を取るメソッドに渡す必要があります。助けてください。
まず、「反対」の実装には重大な問題があります。メソッドに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)
このメソッドは、None
がvalue
である場合にのみ、null
を返します。
質問に対処するために、次の方法があるとします。
def foo(x: Long) = x * 2
通常、Option[Long]
をfoo
に渡すという観点から考えるのではなく、foo
を介してOption
にmap
を「リフティング」する必要があります。
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」値の可能性を(型レベルで)モデル化することです。 map
でOption
を使用すると、Option
にある可能性のある値に対して計算を実行しながら、空である可能性をモデル化することができます。
別の回答ノートとして、getOrElse
を使用してOption
を「救済」することも可能ですが、これは通常Scala(デフォルト値)。
Option [Long]としてxがある場合、x.get
はLongを提供します。
このメソッドは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)
オプションは、副作用をローカライズする方法です(関数は空の値を返すことができます)。そして、計算をオプションに引き上げるのに適したスタイル(オプションはmap&flatMapメソッド)。
val x = Option[Long](10)
x.map { a => a + 10 }
そして、副作用を手動で処理して値を抽出します。
val res = x match {
case Some(a) => s"Value: $a"
case None => "no value"
}
オプションが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
)。
既に述べたように、getOrElseは、質問に直接答える際におそらく探しているものです。
オプションに変換するには、次のこともできることに注意してください。
val myOption = Option(1)
myOptionはSome(1)になります
val myOption = Option(null)
myOptionはNoneになります。