generics - 可空类型的 Scala 泛型约束如何工作

标签 generics scala constraints nullable

我尝试了两种方法来将泛型类型参数限制为可空类型,但两者似乎都有一些意想不到的问题。

第一次尝试(使用 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并不意味着它必须可以为空。例如,NothingAnyRef 的子类型,并且它不可为空。

反过来也是类似的,因为 AnyNull 的父类(super class)型,以及任何 Int也是Any .

关于generics - 可空类型的 Scala 泛型约束如何工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2336204/

相关文章:

scala - 无需指定输入类型即可定义高阶函数的巧妙方法

java - 通过 Windows 7 控制台打开 SBT 时出现问题

c# - 具有泛型的 Lambda

.net - 如何判断 Type 是否实现了 IList<>?

scala - 如何设计不同类型的(几乎)相同的(在 Scala 中)

ios - 布局约束不起作用和/或失败

android - 在约束布局中添加 View 并以编程方式将它们设置为全屏

java - 静态函数调用之前的泛型尖括号

Scala 的 future inside yield

python - 在 Pyomo 约束中定义循环/周期性边界条件