Как scala общие ограничения для типов с нулевым значением
Я пробовал два способа ограничить общий тип параметра нулевым типом, но оба, похоже, имеют некоторые неожиданные проблемы.
Первая попытка (с использованием T <: AnyRef):
scala> def testAnyRefConstraint[T <: AnyRef](option:Option[T]):T = {
| //without the cast, fails with compiler error:
| // "found: Null(null) required: T"
| option getOrElse null.asInstanceOf[T]
| }
testAnyRefConstraint: [T <: AnyRef](Option[T])T
scala> testAnyRefConstraint(Some(""))
res0: java.lang.String =
scala> testAnyRefConstraint(Some(0))
<console>:16: error: inferred type arguments [Int] do not conform to method testAnyRefConstraint type parameter bounds [T <: AnyRef]
testAnyRefConstraint(Some(0))
Это похоже на то, что я хочу, но я не понимаю, почему нуль нужно отличать от T.
Вторая попытка (с использованием T > : Null):
scala> def testNullConstraint[T >: Null](option:Option[T]):T = {
| option getOrElse null
| }
testNullConstraint: [T >: Null](Option[T])T
scala> testNullConstraint(Some(""))
res2: java.lang.String =
scala> testNullConstraint(Some(0))
res3: Any = 0
Это не требует нажатия на null, но позволяет передавать AnyVals и преобразовывать тип в любой, что не то, что я искал.
Кто-нибудь знает, почему эти два разных подхода работают так, как они делают?
Ответы
Ответ 1
def testAnyRefConstraint[T >: Null <: AnyRef](option:Option[T]):T = {
option getOrElse null
}
Я чувствовал себя действительно глупо, когда впервые сделал эту ошибку. Просто потому, что что-то расширяется AnyRef
, не означает, что он должен быть нулевым. Например, Nothing
является подтипом AnyRef
, и он не может быть нулевым.
Другой способ аналогичен, потому что Any
является супертипом Null
, а любой Int
также является Any
.