从 java.lang.Long 创建 Scala Option 时的意外行为
Unexpected behavior when creating Scala Option from java.lang.Long
给定以下代码:
val javaLong: java.lang.Long = null
val opt: Option[Long] = Option(javaLong)
我预计 opt 为 None
但由于某些原因它是 Some(0)
。我还发现了这个 bug 并且隐式转换似乎发生在选项的 apply 方法之前。
我认为这仍然是一个错误,因为人们不会期望这种行为,我想知道是否有任何解决方法或一些更好的方法来包装空值。
更新:
上面的代码只是一个简化的部分。真实的例子是这样的:
Person(Option(doc.getLong()))
人在哪里:
case class Person(id: Option[Long])
方法doc.getLong()
是java方法returnsjava.lang.Long
到Option[Long]
的转换实际上不仅仅是到Option
的转换,也是从Java
到Scala
的Long
的隐式转换的 Long
.
val javaLong: java.lang.Long = null
// javaLong: Long = null
val long: java.lang.Long = javaLong
// long: Long = null
val long: Long = javaLong
// long: Long = 0
首先我们有从 Java
的 Long
到 Scala
的 Long
的隐式转换,这显然从 [=24] 中产生了 0
=].
只有这样我们才能转换为 Option
。
如果我们将 Java
的 Long
指定为 Option
的类型,那么我们会得到 None
而不是 Some(0)
:
val opt: Option[java.lang.Long] = Option(javaLong)
// opt: Option[Long] = None (here it's Java's Long)
我们终于可以将 Option[java.lang.Long]
转换为使用 Scala
的 Long
:
val opt: Option[Long] = Option(javaLong).map(_.toLong)
// opt: Option[Long] = None (here it's Scala's Long)
给定以下代码:
val javaLong: java.lang.Long = null
val opt: Option[Long] = Option(javaLong)
我预计 opt 为 None
但由于某些原因它是 Some(0)
。我还发现了这个 bug 并且隐式转换似乎发生在选项的 apply 方法之前。
我认为这仍然是一个错误,因为人们不会期望这种行为,我想知道是否有任何解决方法或一些更好的方法来包装空值。
更新: 上面的代码只是一个简化的部分。真实的例子是这样的:
Person(Option(doc.getLong()))
人在哪里:
case class Person(id: Option[Long])
方法doc.getLong()
是java方法returnsjava.lang.Long
到Option[Long]
的转换实际上不仅仅是到Option
的转换,也是从Java
到Scala
的Long
的隐式转换的 Long
.
val javaLong: java.lang.Long = null
// javaLong: Long = null
val long: java.lang.Long = javaLong
// long: Long = null
val long: Long = javaLong
// long: Long = 0
首先我们有从 Java
的 Long
到 Scala
的 Long
的隐式转换,这显然从 [=24] 中产生了 0
=].
只有这样我们才能转换为 Option
。
如果我们将 Java
的 Long
指定为 Option
的类型,那么我们会得到 None
而不是 Some(0)
:
val opt: Option[java.lang.Long] = Option(javaLong)
// opt: Option[Long] = None (here it's Java's Long)
我们终于可以将 Option[java.lang.Long]
转换为使用 Scala
的 Long
:
val opt: Option[Long] = Option(javaLong).map(_.toLong)
// opt: Option[Long] = None (here it's Scala's Long)