我有一些需要调用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) )
但得到了这个编译错误
Error:(335, 44) type mismatch; found : Any required: Integer bar.getOrElse(null),
这样做的正确习惯是什么?
您不需要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)) ^
问题是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 ^
所以你必须将你Option
的类型参数转换为可以null
在以可空的方式展开之前的类型参数.
我能立刻想到的最快方式:
scala> new Foo(bar.map(x => x: java.lang.Integer).orNull) res18: Foo = Foo@cdc45e
编辑:在这里,我想到了更通用的方法!
implicit class RichOption[A](o: Option[A]) { def toRef[B >: Null](implicit f: A => B): B = o.map(f).orNull }
现在你可以写new Foo(bar.toRef)
:)