Scala Option(null)はNoneとして期待されていましたが、Some(0)を取得しました


回答:


17

あなたは混ぜIntているjava.lang.Integerので

val i: java.lang.Integer = null
val o: Option[Int] = Option(i)

暗黙的に変換する

val o: Option[Int] = Option(Integer2int(i))

なる

val o: Option[Int] = Option(null.asInstanceOf[Int])

したがって

val o: Option[Int] = Some(0)

で作業したい場合はjava.lang.Integer

val o: Option[java.lang.Integer] = Option(i)
// o: Option[Integer] = None

2
これは最近どこかで尋ねられたので、それは本当の落とし穴です。多分問題は推論に依存しています:Option[Integer](i).map(_.intValue)それが何をしているのかを言っているので、私には最も慣用的なようです。また、を使用-Xlintしてval o
som-snytt

ボクシングラウンドトリップを回避するには、 `val x:Option [Int] = Option(i).asInstanceOf [Option [Int]]` Integerが推測されます。
som-snytt

7

これはOption、を作成Intして1つのステップでに変換しているために発生しているようです(@MarioGalicの回答では、これが発生している理由が説明されています)。

これはあなたが望むことをします:

scala> val o: java.lang.Integer = null
o: Integer = null

scala> val i: Option[Int] = Option(o).map(_.toInt)
i: Option[Int] = None

scala> val o1: java.lang.Integer = 1
o1: Integer = 1

scala> val i1: Option[Int] = Option(o1).map(_.toInt)
i1: Option[Int] = Some(1)

他の答えでは、私は提案しました_.intValue。変換呼び出しのみが保存されると思います。
som-snytt

1

以前に同じ問題に直面しました。この疑わしい動作はScalaチームに知られています。それを変えるとどこかで何かが壊れるようです。https://github.com/scala/bug/issues/11236およびhttps://github.com/scala/scala/pull/5176を参照してください


2
本当に疑わしい動作はnull整数として扱われています。これはおそらく、ポインタCに割り当てることができる場所からの二日酔いです0。しかし、これは結果のポインタが0であることを意味するものではないため、でも2つを切り替えるのは危険Cです。
ティム

Integerほとんどの場合、Javaコードからのものであるため、「nullを整数として扱わない」は実用的なアドバイスではありません。そして、を使用して、この整数がnull可能かどうかを明示的にチェックしOption.applyます。したがって、安全でない操作を明示的に実行しないと、予期しない出力が得られます。
simpadjo

ポイントは、根本的な原因がJavaである場合、「疑わしい動作」についてScalaを責めることはできないということです。実用的なアドバイスは、暗黙の変換を使用するのではなく、Java型から同等のScala型に明示的に変換することです。(したがって、JavaConvertersではなくJavaConversion
ティム

1
まあ、私はできるし、この場合にコンパイルエラー/警告を出さなかったのはScalaのせいです。実行時のクラッシュでも良いでしょう。私の会社だけでも、Scalaで5年以上の経験を持つ2人の開発者がこの問題に直面しています。
simpadjo

1
@Timを呼び出すだけで、ランタイムクラッシュが発生しやすくなりますtheInteger.intValue()。そのクラッシュを回避するために、追加のランタイムチェックが必要になります。古いバージョンのScalaでは、この変換によって実際にNPEが生成されました。バグとして報告され、現在の動作に修正されました。私はScalaのエキスパートではありませんが、歴史的なコンテキストとしてscala-dev#355scala#5176を掘り下げました。
アマロイ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.