使用isDefinedAt检查是否接受类型而不是值

时间:2014-07-21 10:46:16

标签: scala pattern-matching

我有一个案例,我希望使用isDefinedAt来检查部分函数是否接受类型,而不是特定值。

val test: PartialFunction[Any, Unit] = { 
  case y: Int => ???
  case ComplexThing(x, y, z) => ??? 
}

在这里,您可以执行test isDefinedAt 1之类的操作来检查是否接受该值,但是,我真正想要做的是检查所有Int的接受程度(更具体地说,在我的情况下,我要检查的类型很难初始化(它有很多依赖项),所以我真的想避免在可能的情况下创建一个实例 - 目前我只是使用null s,感觉很难看。不幸的是,没有test.isDefinedAt[Int]

我并不担心它只接受某种类型的实例 - 我只想知道这种类型是否完全不可能被接受。

2 个答案:

答案 0 :(得分:2)

无法让PartialFunction执行此操作。实际上,由于类型擦除,在运行时对类型进行操作可能很困难。如果您希望能够在编译时验证类型,则可以改为使用类型类:

class AllowType[-T] {
  def allowed = true
}

object AllowType {
  implicit object DontAllowAnyType extends AllowType[Any] {
    override def allowed = false
  }
}

implicit object AllowInt extends AllowType[Int]
implicit object AllowString extends AllowType[String]

def isTypeAllowed[T](implicit at: AllowType[T]) = at.allowed

isTypeAllowed[Int] // true
isTypeAllowed[Double] // false

答案 1 :(得分:0)

答案似乎是这根本不可能 - 还有其他方法可以做到这一点(如在wingedsubmariner's answer中),但这需要复制信息(这使得它毫无意义,因为这样做是为了避免这种情况,或者改变不使用部分功能(由外部API决定)。

最好的解决方案就是使用null来填充依赖项来创建要检查的实例。这很丑陋,并且有自己的问题,但如果没有实质性的改变,它似乎是最好的。

test.isDefinedAt(ComplexThing(null, null, null))