了解与子类的模式匹配

Kev*_*ith 2 scala pattern-matching

Lift有Box案例类.

我写了以下方法来模式匹配Box[A]:

scala> import net.liftweb.common._
import net.liftweb.common._

scala> def foo[A](box: Box[A]) = box match { 
     |   case Empty | Failure(_, _, _) => true
     |   case Full(_)                  => false
     | }
foo: [A](box: net.liftweb.common.Box[A])Boolean
Run Code Online (Sandbox Code Playgroud)

我写了这个方法来学习是否会在案例中模式匹配ParamFailure,这是一个子类.FailureFailure(_, _, _)

scala> val pf: Box[String] = ParamFailure("a", Empty, Empty, "blah")
pf: net.liftweb.common.Box[String] = ParamFailure(a, Empty, Empty, blah)
Run Code Online (Sandbox Code Playgroud)

而且,确实如此.

scala> foo(pf)
res9: Boolean = true
Run Code Online (Sandbox Code Playgroud)

我不清楚为什么ParamFailure会匹配Failure(_, _, _).这是为什么?

Rex*_*err 6

这是继承的全部要点.如果S是子类C,那么你应该能够S 绝对使用你使用的所有地方C(这称为Liskov替换原则).

包括模式匹配.

现在,如果你特别想告诉你是否有a S而不是a C,你可以检查它:

class C {}
class S extends C {}
val c: C = new S
c match {
  case s: S => println("Actually, I was an S")
  case _ => println("Guess I was some other kind of C")
}
Run Code Online (Sandbox Code Playgroud)

但如果你问它是不是C,答案是肯定的:

c match {
  case c2: C => println("Yes, of course I am a C!")
  case _ => println("This would be super-weird.")
}
Run Code Online (Sandbox Code Playgroud)

再次,添加模式匹配在此不做任何改动; 无论您是否知道类型,然后手动提取参数,或者Scala是否有助于为您提供标识符,它的工作方式相同.

case class P(p: Boolean) {}
object T extends P(true) {}
val p: P = T
p match {
  case P(tf) => println(tf)
  case _ => println("You will never reach here.")
}
Run Code Online (Sandbox Code Playgroud)