Reputation: 2593
I'm writing a function to get an entry from a JSONObject
. Since it is JSON the entry by the input name may or may not exist and so the function return an Option
which will be None
when the Try
fails or if the value is NULL
on success. The function fails to compile and errors about incorrect return type.
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
}
Error:
Expression of type Option[Any] doesn't conform to expected type Option[T]
Can someone tell me what I'm doing wrong here? Also, is this the idiomatic way to approach the problem?
Update:
Changing to the below works
def tryGet[T](jsonObject: JSONObject, name: String): Option[T] = {
Try(jsonObject.get(name))
.filter(!JSONObject.NULL.equals(_))
.map(_.asInstanceOf[T])
.toOption
}
Upvotes: 4
Views: 7009
Reputation: 1085
I don't think you need the null check, and "None" and "T" are two possible result in the map, so the type will be mapped to Any instead of "T" in your code. Check this:
Try(jsonObject.get(name)).map( _.asInstanceOf[T]).toOption
Then you might need something like this:
val NullJson:Option[T] = None
Try(jsonObject.get(name)).map( x=>if(x.equals(null)) NullJson else Option(x.asInstanceOf[T])).toOption.flatten
Upvotes: 0
Reputation: 55569
The problem is with this line:
.map( x => if(x.equals(null)) None else x.asInstanceOf[T])
This has type `Option[Nothing]` ^ ^ This has type `T`
You have both an Option[Nothing]
and a T
in the if/else statement. The result type of if/else is the least upper-bound (the nearest common type) of the result type of if
and the result type of else
. In this case, they have nothing in common but Any
. So the the result is Try[Any]
which gets converted to Option[Any]
by toOption
.
If you really need to check for null
, use filter
instead.
def tryGet[T](jsonObject: JSONObject, name: String): Option[T] =
Try(jsonObject.get(name))
.map(_.asInstanceOf[T])
.filter(_ != null)
.toOption
Upvotes: 4