opu*_*111 6 null scala java-api scala-option
我有一些需要调用Java API的Scala代码
Java API接受可能为null的参数.我的Scala当然使用了Option.
举例来说,假设我有一个Java对象的构造Foo(Integer),其中Integer可能null.我想给Scala打电话bar: Option[Int].
我试过这个
import scala.collection.JavaConversions._
import scala.collection.JavaConverters._
val foo = Foo( bar.getOrElse(null) )
Run Code Online (Sandbox Code Playgroud)
但得到了这个编译错误
Error:(335, 44) type mismatch;
found : Any
required: Integer
bar.getOrElse(null),
Run Code Online (Sandbox Code Playgroud)
这样做的正确习惯是什么?
您不需要Java方法来重现此问题:
scala> import scala.collection.JavaConversions._
import scala.collection.JavaConversions._
scala> import scala.collection.JavaConverters._
import scala.collection.JavaConverters._
scala> class Foo(a: java.lang.Integer)
defined class Foo
scala> val bar: Option[Int] = Some(5)
bar: Option[Int] = Some(5)
scala> new Foo(bar.getOrElse(null))
<console>:16: error: type mismatch;
found : Any
required: Integer
new Foo(bar.getOrElse(null))
^
Run Code Online (Sandbox Code Playgroud)
问题是Int不可能null,所以类型bar.getOrElse(null)是Any.
scala> bar.getOrElse(null)
res0: Any = 5
scala> bar.orNull
<console>:15: error: Cannot prove that Null <:< Int.
bar.orNull
^
Run Code Online (Sandbox Code Playgroud)
所以你必须将你Option的类型参数转换为可以null在以可空的方式展开之前的类型参数.
我能立刻想到的最快方式:
scala> new Foo(bar.map(x => x: java.lang.Integer).orNull)
res18: Foo = Foo@cdc45e
Run Code Online (Sandbox Code Playgroud)
编辑:在这里,我想到了更通用的方法!
implicit class RichOption[A](o: Option[A]) {
def toRef[B >: Null](implicit f: A => B): B = o.map(f).orNull
}
Run Code Online (Sandbox Code Playgroud)
现在你可以写new Foo(bar.toRef):)
我一发布问题,就在相关列表中找到答案(抱歉)
这是一个解决方案
val foo = Foo(bar.getOrElse(null).asInstanceOf[java.lang.Integer])
Run Code Online (Sandbox Code Playgroud)
有点笨重。有人有更好的吗?
| 归档时间: |
|
| 查看次数: |
1498 次 |
| 最近记录: |