Coursera Scala 4-6:模型匹配
匹配值
val times = 1
times match {
case 1 => "one"
case 2 => "two"
case _ => "some other number"
}
List(('a',1), ('b',2), ('a',1)) match {
case Nil => println("null")
case (C, n) :: ps => (C, n+1) :: ps 得到List(('a',2), ('b',2), ('a',1))
case p :: ps => p 得到('a',1)
case p :: ps => ps 得到List(('b',2), ('a',1))
}
}
匹配类型
def bigger(o: Any): Any = {
o match {
case i: Int if i < 0 => i - 1
case i: Int => i + 1
case d: Double if d < 0.0 => d - 0.1
case d: Double => d + 0.1
case text: String => text + "s"
}
}
匹配类成员
def calcType(calc: Calculator) = calc match {
case _ if calc.brand == "hp" && calc.model == "20B" => "financial"
case _ if calc.brand == "hp" && calc.model == "48G" => "scientific"
case _ if calc.brand == "hp" && calc.model == "30B" => "business"
case _ => "unknown"
}
样本类Case Class
使用样本类可以方便得存储和匹配类的内容。你不用new关键字就可以创建它们
scala> case class Calculator(brand: String, model: String)
defined class Calculator
scala> val hp20b = Calculator("hp", "20b")
hp20b: Calculator = Calculator(hp,20b)
使用样本类进行模式匹配:
e match{
case pattern => expr
}
在没有匹配项时抛出 MatchError
Pattern可以是:
- 小写字母开头表示变量(保留字除外) 用于绑定值到这个变量
- 大写开头表示常量 两者是否相等来进行匹配(==)
构造器pattern C(p1,....,pn) 匹配所有C类型(或子类型)通过p1...p构造的
(注意类的定义要用case class)
同样的变量只能在Pattern出现一次
顺序匹配下去
trait Expr
case class Number(n:Int) extends Expr
case class Sum(e1:Expr,e2:Expr) extends Expr
object exprs {
def show(e:Expr): String = e match {
case Number(x) => x.toString
case Sum(l.r) => show(l)+"+"+show(r)
}
}
show(Sum(Number(1),Number(44))) > res0:String=1+44
例子:
trait Expr {
def isNumber: Boolean
def isSum: Boolean
def numValue: Int
def leftOp: Expr
def rightOp: Expr
def show():String = this match{
case Number(n) => n+""
case Sum(e1,e2) => e1+"+"+e2
}
}
另一个例子:
Scala代码
def show(e: Expr): String = e match {
case Sum(Prod(x1, x2), Prod(x3, x4)) =>
if (x1 == x3) show(x1) + "*" + "(" + show(x2) + "+" + show(x4) + ")"
else if (x1 == x4) show(x1) + "*" + "(" + show(x2) + "+" + show(x3) + ")"
else if (x2 == x3) show(x2) + "*" + "(" + show(x1) + "+" + show(x4) + ")"
else if (x2 == x4) show(x2) + "*" + "(" + show(x1) + "+" + show(x3) + ")"
else show(_Prod(x1, x2)) + "+" + show(_Prod(x3, x4))
case Sum(n1, n2) => show(n1) + "+" + show(n2)
case Prod(Sum(n1, n2), n3) => "(" + show(_Sum(n1, n2)) + ")" + "*" + show(n3)
case Prod(n3, Sum(n1, n2)) => show(n3) + "*(" + show(_Sum(n1, n2)) + ")"
case Prod(n1, n2) => show(n1) + "*" + show(n2)
case _ => e.toString()
}
Reference
http://twitter.github.io/scala_school/zh_cn/basics2.html#match
http://hongjiang.info/scala-pattern-matching-1/