scala中有一个灰常强大的东西,叫做模式匹配。可以理解为Switch,只是比它更加强大。
var sign = -1
val ch:Char = '+'
/**
* 模式匹配:更好用的switch
*/
ch match {
case '-' => sign = -1
case '+' => sign = 1
case _ => sign = 0
}
和switch不同的是,没一个匹配条件后面,不需要break(想到当年写switch,忘记break的痛苦经历、、、),不会掉入下一个分支。
如果想要添加多个case标签,可以不用从case’0’写道case’9’,可以向下面这样做:
ch match {
case '-' => sign = -1
case '+' => sign = 1
case _ if Character.isDigit(ch) => sign = Character.digit(ch,10)
case _ => sign = 0
}
类型模式
//类型模式
var obj : Any = 1024
var o = obj match {
case x:Int => x
case s:String =>Integer.parseInt(s)
case _:BigInt =>Int.MaxValue
case _ => 0
}
列表、元组、数据匹配
var sth = arr match {
case Array(0) => "0" //这个只能匹配Array(0)
case Array(x, y) => x + " " + y //匹配任何带有2个元素的数组
case Array(0, _*) => "0..." //任何以0开始的数组
case _ => "something else"
}
val lkt = List(0, -3, -5, 7, 8)
var value = lkt match {
case 0 :: Nil => "0"
case x :: y :: Nil => x + " " + y
case 0 :: tail => "0..."
case _ => "something else"
}
var pair = (0, 1)
pair match {
case (0, _) => "0..."
case (y, 0) => y + "0"
case _ => "neither is zero"
}
变量中的模式匹配
val (q,r) = BigInt(10) /% 3
上面代码中,会将商和余数分别赋值给q,r
for循环中的模式匹配
for ((k, v) <- System.getProperties())
println(k + "->" + v)
for ((k, "") <- System.getProperties())
println(k)
for ((k, v) <- System.getProperties() if v=="")
println(k)
第二个和第三个for循环只会打印value为空的K键
样例类
abstract class Amount
val amt:Amount = new Dollar(11.2)
case class Dollar (value: Double) extends Amount
case class Currency(value:Double,unit: String) extends Amount
case object Nothing extends Amount
var v = amt match {
case Dollar(v) => "$" + v
case Currency(_,u) => ""+u
case Nothing => ""
}
当声明样例类时,会有以下几件事情自动发生
构造器中每一个参数都成为val,除非显示声明为var
在伴生对象中提供apply方法,可以不用new关键字构造出相应对象,比如:Dollar(11.2)
将自动生成toString,hashCode,equals,copy等方法,除非有该方法的定义
copy方法
val am = Currency(29.25,"EUR")
val price = am.copy(value = 19.25) //Currency(19.25,"EUR")
val pr = am.copy(unit = "CHF") //Currency(29.25,"CHF")
偏函数
偏函数,一个并非对所有输入值都定义的函数
val f:PartialFunction[Char,Int] = {case '+' => 1;case '-' => -1}