了解子类的模式匹配 [英] Understanding Pattern Matching with Sub-classes

查看:41
本文介绍了了解子类的模式匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Lift 有 Box 案例类.

Lift has the Box case class.

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

I wrote the following method to pattern match on a 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

我编写这个方法是为了了解 ParamFailure(Failure 的子类)是否会在 Failure(_, _, _) 案例.

I wrote this method to learn if ParamFailure, which is a sub-class of Failure, would pattern match on the Failure(_, _, _) case.

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

而且,它做到了.

scala> foo(pf)
res9: Boolean = true

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

It's not clear to me why ParamFailure would match to Failure(_, _, _). Why is that?

推荐答案

这就是继承的全部意义.如果 SC 的子类,那么你应该可以使用 S 绝对在任何地方你使用 C(这称为 Liskov 替换原则).

This is the whole point of inheritance. If S is a subclass of C, then you should be able to use S absolutely everywhere that you use C (this is called the Liskov Substitution Principle).

包括模式匹配.

现在,如果你特别想知道你是否有一个 S 而不是 C,你可以检查它:

Now, if you specifically want to tell if you have an S as opposed to a C, you can check for it:

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")
}

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

But if you ask if it's a C, the answer is yes:

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

同样,添加模式匹配在这里没有任何改变;无论您知道类型然后手动提取参数,还是 Scala 为您提供标识符,它的工作方式都是相同的.

Again, adding pattern matching changes nothing here; whether you know the type and then pull out the parameters by hand, or whether Scala helpfully gives you identifiers for them, it works the same way.

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.")
}

这篇关于了解子类的模式匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆