Последняя ошибка вызывает несколько подозрений: похоже, вы заключаете Java Optional
в Scala Option
. Вместо этого я бы ожидал, что это не удастся, потому что вы пытаетесь flatMap
другого типа, что-то вроде
error: type mismatch;
found : java.util.Optional[T] => java.util.Optional[T]
required: java.util.Optional[T] => Option[?]
Это, кажется, соответствует вашему требованию:
import java.util.Optional
def getObjectFromNullableOptional[T](opt: Optional[T]): T =
Optional.ofNullable(opt).orElse(Optional.empty).orElse(null.asInstanceOf[T])
assert(getObjectFromNullableOptional(null) == null)
assert(getObjectFromNullableOptional(Optional.empty) == null)
assert(getObjectFromNullableOptional(Optional.of(1)) == 1)
Вы можете поиграть с этим здесь, в Scast ie.
Обратите внимание, что asInstanceOf
скомпилирован с приведением, а не с фактическим вызовом метода, поэтому этот код не будет выбрасывать a NullPointerException
.
Вы также можете go сделать что-то более близкое к вашему исходному решению, немного помогая выводу типа Scala:
def getObjectFromNullableOptional[T](opt: Optional[T]): T =
Optional.ofNullable(opt).flatMap((o: Optional[T]) => o).orElse(null.asInstanceOf[T])
Или альтернативно используя Scala s identity
:
def getObjectFromNullableOptional[T](opt: Optional[T]): T =
Optional.ofNullable(opt).flatMap(identity[Optional[T]]).orElse(null.asInstanceOf[T])
Для решения, использующего Scala 'Option
, вы можете сделать что-то очень близкое:
def getObjectFromNullableOption[T](opt: Option[T]): T =
Option(opt).getOrElse(None).getOrElse(null.asInstanceOf[T])
Обратите внимание, что вы идете к * Решение 1029 * с Scala Option
позволяет избежать явного указания типа функции:
def getObjectFromNullableOption[T](opt: Option[T]): T =
Option(opt).flatMap(identity).getOrElse(null.asInstanceOf[T])
Я не совсем уверен в деталях, но я считаю, что проблема заключается в что при использовании java.util.Optional
вы передаете Scala Function
в Optional.flatMap
, что занимает Java Function
. Компилятор Scala может преобразовать это автоматически для вас, но, очевидно, вы должны указать c и указать тип, чтобы это работало, по крайней мере, в этом случае.
Примечание относительно вашего исходного кода: вы требуется T
, чтобы быть супертипом Null
, но это не обязательно.
У вас есть лучший контекст относительно того, что вы делаете, но в качестве общего совета обычно лучше избегать null
s как можно больше утечки в коде Scala.