簡體   English   中英

了解與子類的模式匹配

[英]Understanding Pattern Matching with Sub-classes

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

我寫了這個方法來了解ParamFailure ,它是一個Failure的子類,是否會在Failure(_, _, _)情況下模式匹配。

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(_, _, _) 這是為什么?

這是繼承的全部要點。 如果SC的子類,那么你應該能夠在任何使用C 地方絕對使用S (這稱為Liskov替換原則 )。

包括模式匹配。

現在,如果你特別想知道你是否有一個S而不是一個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")
}

但如果你問它是否是C ,答案是肯定的:

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

再次,添加模式匹配在此不做任何改動; 無論您是否知道類型,然后手動提取參數,或者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.")
}

這就是規范中定義案例類的方式。

提取器接受case類的實例(即,unapply方法接受C)並返回第一個參數列表的元素。

您可以想象其他定義,例如要求擦除類型完全相同,或者至少productArity是相同的。

模式匹配被定義為測試形狀 ,而不僅僅是或主要作為類型測試或相等測試。

實際上, 構造函數模式的規范並沒有直接解決子類型:

該模式匹配從構造函數調用c(v1,...,vn)創建的所有對象

當然,子類構造必然會調用該構造函數。

一個case類可以擴展另一個case類時 ,可能會有更高的期望,模式匹配會區分子類,但那是在我的時間之前:

$ scala27
Welcome to Scala version 2.7.7.final (OpenJDK 64-Bit Server VM, Java 1.6.0_33).
Type in expressions to have them evaluated.
Type :help for more information.

scala> case class A(i: Int)                       
defined class A

scala> case class B(j: Int, s: String) extends A(j)
defined class B           

scala> (B(7,"hi"): Any) match { case A(7) => 1 case B(_,_) => 2 }
res1: Int = 1

scala> B(7,"hi").productArity                      
res2: Int = 2

我從文法學校知道,有些駱駝有一個駝峰,有些有兩個。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM