我尝试了两种方法来将泛型类型参数限制为可空类型,但两者似乎都有一些意想不到的问题。
第一次尝试(使用 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's type parameter bounds [T <: AnyRef]
testAnyRefConstraint(Some(0))
这似乎完全符合我的要求,但我不明白为什么需要将 null 强制转换为 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 并将类型转换为 any,这不是我想要的。
有谁知道为什么这两种不同的方法以它们的方式工作?
最佳答案
def testAnyRefConstraint[T >: Null <: AnyRef](option:Option[T]):T = {
option getOrElse null
}
当我第一次犯这个错误时,我感到非常愚蠢。仅仅因为某事扩展
AnyRef
并不意味着它必须可以为空。例如,Nothing
是 AnyRef
的子类型,并且它不可为空。反过来也是类似的,因为
Any
是 Null
的父类(super class)型,以及任何 Int
也是Any
.
关于generics - 可空类型的 Scala 泛型约束如何工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2336204/