ScalaのオプションでJavaのnullを返すメソッドをラップする?


107

私がメソッドを持っているとしsession.get(str: String): Stringましょう。それはJavaから来ているので、それがあなたに文字列またはnullを返すかどうかわかりません。

代わりにScalaでこれを処理する簡単な方法はありsession.get("foo") == nullますか?たぶんいくつかの魔法がのように適用されToOption(session.get("foo"))、私はそれをScalaのように扱うことができます

ToOption(session.get("foo")) match {
    case Some(_) =>;
    case None =>;
}

4
その他のオプショントリックについては、blog.tmorris.net / scalaoption
cheat

回答:


182

OptionコンパニオンオブジェクトのapplyメソッドはNULL参照からの変換関数として機能します。

scala> Option(null)
res4: Option[Null] = None

scala> Option(3)   
res5: Option[Int] = Some(3)

19

Optionオブジェクトが持っているapplyまさにその方法を:

var myOptionalString = Option(session.get("foo"));

5

Javaオブジェクトを操作する場合、期待どおりに機能しないことに注意してください。

val nullValueInteger : java.lang.Integer = null
val option: Option[Int] = Option(nullValueInteger)
println(option)  // Doesn't work - zero value on conversion

val nullStringValue : String = null
val optionString: Option[String] = Option(nullStringValue)
println(optionString) // Works - None value

1
私はscala 2.11.8で実行しました。2行目でNullPointerExceptionがスローされました。6行目は、期待どおりNoneではなく、Some(null)になりました。
John Lin、

1. optionStringでOptionの代わりにいくつか使用-元の回答で変更されました。2. Scala 2.12.5でのみ確認
DekelM

-3

これは非常に古いトピックですが、いいトピックです!

Try to Optionの例外以外の結果を変換すると、Some ...

scala> Try(null).toOption
res10: Option[Null] = Some(null)

...なぜなら、Tryはnull可能性チェックではなく、例外を機能的に処理するための方法だからです。

例外をキャッチして[オプション]に変換すると、例外が発生した場合にのみ[なし]が表示されます。

scala> Try(1/0).toOption
res11: Option[Int] = None

Tryから得られる値を保持する必要があります。nullの可能性があります。

しかし、標準のlibがときどき混乱することも事実です...

scala> Try(null).toOption
res12: Option[Null] = Some(null)

scala> Option(null)
res13: Option[Null] = None

この動作は少し矛盾していますが、TryとOptionの両方の意図的な使用法を反映しています。

例外をスローする可能性のある式から出てくるものをすべて取得するためにtryを使用し、例外自体は気にしません。

出てくる可能性のある値は、nullである可能性があります。toOptionにNoneが指定されている場合、例外とnullを区別することができません

スタンドアロンでは、オプションを使用して、存在の有無をカプセル化します。したがって、その場合、Some(null)はNoneであり、それは理にかなっています。なぜなら、その場合のnullは、何かの不在を表すからです。ここにはあいまいさはありません。

.toOptionはOption()と同じではないため、どのような場合でも参照の透明性は損なわれないことに注意することが重要です。

本当に例外の安全性 nullの安全性の両方を強制する必要があり、コードが本当にnullと例外を区別する必要がない場合は、両方のパラダイムを組み合わせるだけです!まあ、それはあなたが望んでいることですよね?

あなたはそれを一つの方法で行うことができます...

scala> Try(Option(null)).getOrElse(None)
res23: Option[Null] = None

scala> Try(Option(3/0)).getOrElse(None)
res24: Option[Int] = None

scala> Try(Option(3)).getOrElse(None)
res25: Option[Int] = Some(3)

...または別の...

scala> Try(Option(null)).toOption.flatten
res26: Option[Null] = None

scala> Try(Option(3/0)).toOption.flatten
res27: Option[Int] = None

scala> Try(Option(3)).toOption.flatten
res28: Option[Int] = Some(3)

...またはそれらの別の途方もなく醜い...

scala> Option(Try(null).getOrElse(null))
res29: Option[Null] = None

scala> Option(Try(3/0).getOrElse(null))
res30: Option[Any] = None

scala> Option(Try(3).getOrElse(null))
res31: Option[Any] = Some(3)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.