Scala选项类型未按预期推断

Scala选项类型未按预期推断,scala,scala-option,Scala,Scala Option,我正在编写一个函数,从JSONObject获取一个条目。由于它是JSON,输入名称的条目可能存在,也可能不存在,因此函数返回一个选项,当Try失败或成功时,该选项将为None。函数编译失败,返回类型错误 def tryGet[T](jsonObject: JSONObject, name: String): Option[T] = { Try(jsonObject.get(name)) .map(x => if(JSONObject.NULL.equals(x)) None e

我正在编写一个函数,从
JSONObject
获取一个条目。由于它是JSON,输入名称的条目可能存在,也可能不存在,因此函数返回一个
选项
,当
Try
失败或成功时,该选项将为
None
。函数编译失败,返回类型错误

def tryGet[T](jsonObject: JSONObject, name: String): Option[T] = {
  Try(jsonObject.get(name))
    .map(x => if(JSONObject.NULL.equals(x)) None else x.asInstanceOf[T])
    .toOption
}
错误:

类型选项[Any]的表达式不符合预期的类型选项[t]

有人能告诉我我做错了什么吗?还有,这是解决问题的惯用方法吗

更新:

改为下面的作品

def tryGet[T](jsonObject: JSONObject, name: String): Option[T] = {
    Try(jsonObject.get(name))
      .filter(!JSONObject.NULL.equals(_))
      .map(_.asInstanceOf[T])
      .toOption
}

我认为您不需要空检查,映射中的两个可能结果是“None”和“t”,因此类型将映射到代码中的Any而不是“t”。选中此项:

Try(jsonObject.get(name)).map( _.asInstanceOf[T]).toOption
那么你可能需要这样的东西:

val NullJson:Option[T] = None
Try(jsonObject.get(name)).map( x=>if(x.equals(null)) NullJson else Option(x.asInstanceOf[T])).toOption.flatten

这一行的问题在于:

.map( x => if(x.equals(null)) None else x.asInstanceOf[T])
This has type `Option[Nothing]` ^         ^ This has type `T`
if/else语句中既有
选项[Nothing]
又有
T
。if/else的结果类型是
if
的结果类型和
else
的结果类型的最小上界(最接近的公共类型)。在这种情况下,它们没有任何共同点,只有
Any
。因此,结果是
Try[Any]
,它通过
toOption
转换为
Option[Any]

如果确实需要检查
null
,请改用
filter

def tryGet[T](jsonObject: JSONObject, name: String): Option[T] =
    Try(jsonObject.get(name))
        .map(_.asInstanceOf[T])
        .filter(_ != null)
        .toOption

是的,我试过了,它在运行时抛出“线程中的异常”main“java.lang.ClassCastException:org.json.JSONObject$Null不能转换为java.lang.String”,因为它试图将Null转换为字符串。@broun您应该编写您正在使用的json库。我认为您的json库没有返回
null
,而是返回非null对象
org.json.JSONObject$null
是的,只是认为它返回了一个自定义的null类型。我正在检查java null,而不是在try中添加过滤器。谢谢你的帮助。