从java.lang.Long创建Scala选项时出现意外行为

Dmi*_*ach 6 null scala implicit

给出以下代码:

val javaLong: java.lang.Long = null
val opt: Option[Long] = Option(javaLong)
Run Code Online (Sandbox Code Playgroud)

我期望选择,None但出于某种原因,它是Some(0).我也发现了这个bug,看来隐式转换发生在option的apply方法之前.我认为这仍然是一个错误,因为人们不会期望这种行为,我想知道是否有任何解决方法或一些更好的方法来包装空值.

更新:上面的代码只是一个简化的部分.真实的例子是这样的:

Person(Option(doc.getLong()))
Run Code Online (Sandbox Code Playgroud)

人是:

 case class Person(id: Option[Long])
Run Code Online (Sandbox Code Playgroud)

和方法doc.getLong()是返回java.lang.Long的java方法

Xav*_*hot 3

转换为Option[Long]实际上不仅仅是到 an 的转换,而且还是从s到sOption的隐式转换。ScalaLongJavaLong

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
Run Code Online (Sandbox Code Playgroud)

Java首先,我们有从sLongScala's 的隐式转换Long,这显然会0产生null.

只有这样我们才能转换为Option.

如果我们指定JavaLong指定为 our 的类型Option,那么我们会得到None而不是Some(0)

val opt: Option[java.lang.Long] = Option(javaLong)
// opt: Option[Long] = None (here it's Java's Long)
Run Code Online (Sandbox Code Playgroud)

我们终于可以将 转换Option[java.lang.Long]为 use Scala's Long

val opt: Option[Long] = Option(javaLong).map(_.toLong)
// opt: Option[Long] = None (here it's Scala's Long)
Run Code Online (Sandbox Code Playgroud)

  • `Option` 按预期工作,奇怪的是,当一个可以为 `null` 而另一个不能为 `null` 时,期望 `java.lang.Long` 和 `Long` 相同!对于任何测试“null”值的泛型,您都会遇到同样的问题。 (2认同)