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中添加过滤器。谢谢你的帮助。