使用null参数从Scala调用Java API

 Amy爱爸爸爱妈妈 发布于 2022-12-04 02:42

我有一些需要调用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),

这样做的正确习惯是什么?

1 个回答
  • 您不需要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):)

    2022-12-11 02:14 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有