如何否定 Scala 中模式匹配中的类型?

ser*_*eda 1 scala pattern-matching

使用此代码 println 将仅针对指定的异常执行。我想知道是否可以否定该行以使其对未指定的所有其他异常执行。我知道可以使用 2 个案例,但我想知道是否可以使用一个案例来完成。

val myHandler: PartialFunction[Throwable, Unit] = {
  case e @ (_: MappingException | _: ParseException | _: SomeOtherException) =>
   println("Got it")
}
Run Code Online (Sandbox Code Playgroud)

Lui*_*rez 6

AFAIk 你不能用单个匹配来做到这一点,但你可以创建自己的自定义提取器,以防你需要在多个地方复制这种行为。

import scala.reflect.ClassTag

final class Not[A : ClassTag] {
  def unapply(any: Any): Boolean = any match {
    case _: A => false
    case _ => true
  }
}
object Not {
  def apply[A : ClassTag]: Not[A] = new Not
}
Run Code Online (Sandbox Code Playgroud)

你可以这样使用:

final val NotAnInt = Not[Int]

10 match {
  case NotAnInt() => false
  case _ => true
}
// res: Boolean = true

"10" match {
  case NotAnInt() => true
  case _ => false
}
// res: Boolean = true
Run Code Online (Sandbox Code Playgroud)

但是,请记住,这将具有任何类型检查的所有限制,例如无法区分List[Int]List[String]由于擦除;并被认为是一种不好的做法

我建议研究一种类型类方法,例如,我相信Shapeless提供了一种否定方法。


您可以在此处看到运行的代码