match表达式
- 类似Java switch语句
- 能处理类型所有类型
- 不需要break
- 能够生成值
val firstArg=if(args.length>0) args(0) else ""
firstArg match{
case "salt" => println("pepper")
case "chips" => println("salsa")
case "eggs" => println("bacon")
case _ => println("huh?") //以上未列出的值,使用“_”表示
}
样例类的模式匹配
- 模式匹配
- 检查某个值(value)是否匹配某一个模式的机制,一个成功的匹配同时会将匹配值解构为其组成部分
//基本模式匹配
def matchTest(x:Int):String = x match{
case 1 => "one"
case 2 => "two"
case _ => "many"
}
matchTest(3) //many
matchTest(1) //one
//模式守卫(在模式后面加上if条件)
def matchTest2(x:Int):String = x match{
case i if i==1 => "one"
case i if i==2 => "two"
case _ => "many"
}
matchTest2(3) //many
matchTest2(1) //one
//仅匹配类型
def matchTest3(x:Any):String = x match{
case x:Int => "Int"
case x:String => "String"
case _ => "Any"
}
matchTest3(3.0) //Any
matchTest3(1) //Int
//样例类的模式匹配
def matchTest4(x:Student) = x match{
case Student(name,19) => println(name)
case Student("Tom",age) => println(age)
case Student(name,age) => println(name,age)
case _ => println("no matches")
}
matchTest4(Student("jason",19)) //jason
matchTest4(Student("Tom",32)) //32
matchTest4(Student("Amy",25)) //Amy,25
非样例类的模式匹配
- 单例对象中指定unapply( )方法时,称为提取器对象
- unapply( )方法接受一个实例对象,返回最初创建它所用的参数
class Student(_name:String,_age:Int){
var name = _name
var age = _age
}
object Student{
def apply(name:String,age:Int):Student = new Student(name,age)
def unapply(arg:Student):Option[(String,Int)] = {
if(arg==null){
None
}else{
Some(arg,name,arg.age)
}
}
}
def matchTest(x:Student) = x match{
case Student(name,age) if age<=20 => println("young")
case Student(name,age) if age>20 => println("old")
}
matchTest(Student("jason",19)) //young
偏函数
- 偏函数是只对函数定义域的一个子集进行定义的函数
- partialFunction[-A,+B]是一个特质
- A为函数定义域,B为偏函数返回值类型
- apply()
- isDefinedAt()
//自定义偏函数
val inc = new PartialFunction[Any,Int]{
def apply(any:Any) = any.asInstanceOf[Int]+1
def isDefinedAt(any:Any) = if(any.isInstanceOf[Int] true else false)
}
List(1,2,3,"four").collect(inc)
//返回一个偏函数
val pf:PartialFunction[Any, Int]={case x:Int=>x+1}
//输出List(2,3,4)
List(1,2,3,"four").collect(pf)
正则表达式
- Scala支持多种正则表达式解析方式
- String.matches()方法
- 正则表达式模式匹配
- scala.util.matching.Regex API
//String.matches
"!123".matches("[a-zA-Z0-9]{4}") //false
"34Az".matches("[a-zA-Z0-9]{4}") //true
//模式匹配,Regex实现了提取器
val regstr = "([a-z]{3})".r //使用.r方法可使任意字符串变成一个regex实例
"abc" match {
case regstr(x)=>println(x)
case _ =>println("xixi")
}
- scala.util.matching.Regex(方法详解)
- findFirstMatchIn() 返回第一个匹配 (Option[Match])
- findAllMatchIn() 返回所有匹配结果(正则迭代器)
- findAllIn() 返回所有匹配结果(字符串数组迭代器)
val str = "{browser:chrome,screen:1024x768,pageName:http://www.baidu.com}"
val reg = "([a-zA-Z]+):([a-zA-Z0-9:/\\.]+)".r
reg.findAllMatchIn(str).foreach(x=>println(s"key:${x.group(1)},value:${x.group(2)}"))
reg.findAllIn(str).foreach(x=>x match {case reg(k,v)=>println(k,v)})
- 捕获分组结果:
val studentPattern:Regex="([0-9a-zA-Z-#() ]+):([0-9a-zA-Z-#() ]+)".r
val input="name:Jason,age:19,weight:100"
for(patternMatch<-studentPattern.findAllMatchIn(input)){
println(s"key: ${patternMatch.group(1)} value: ${patternMatch.group(2)}")
}
- 字符串替换:
//search
val nums = "[0-9]+".r.findAllIn("123 Main Street Suite 2012")
nums.next // -> 123
nums.next // -> 2012
//replace
"[0-9]+".r.replaceFirstIn("234 Main Street Suite 2034", "567") //234->567
"[0-9]+".r.replaceAllIn("234 Main Street Suite 2034", "567") //234、2034->567
- 在字符串中模式匹配
val date = """(\d\d\d\d)-(\d\d)-(\d\d)""".r
"2014-05-23" match {
case date(year, month, day) => println(year,month,day)
}
"2014-05-23" match {
case date(year, _*) => println("The year of the date is " + year)
}
"2014-05-23" match {
case date(_*) => println("It is a date")
}
隐式类
-
隐式类:用implicit关键字修饰的类,其主构造器可用于隐式转换
- 只能在类、Trait、对象(单例对象、包对象)内部定义
- 构造器只能携带一个非隐式参数
- 隐式类不能是case class
- 在同一作用域内,不能有任何方法、成员或对象与隐式类同名 -
隐式转换
- 隐式参数、隐式函数
- 隐式转换函数是以implicit关键字声明的带有单个参数的函数
- 这种函数将会自动应用,将值从一种类型转换到另一种类型
案例研究:
//隐式参数
object ImplicitTest {
/**
* Implicit实现隐式参数
*/
object Context{
implicit val str:String = "implicit parameter"
}
object Parameter{
def print(context:String)(implicit prefix:String): Unit ={
println(prefix+":"+context)
}
}
def main(args: Array[String]) {
Parameter.print("Hello")("Scala")
//在此使用隐式参数
import Context._
Parameter.print("Scala")
}
}
运行结果:
Scala:Hello
implicit parameter:Scala
//隐式转换
object ImplicitTest {
/**
* Implicit实现隐式参数
*/
object Context{
implicit val str:String = "implicit parameter"
}
object Parameter{
def print(context:String)(implicit prefix:String): Unit ={
println(prefix+":"+context)
}
}
def main(args: Array[String]) {
Parameter.print("Hello")("Scala")
//在此使用隐式参数
import Context._
Parameter.print("Scala")
}
}
运行结果:
Scala:Hello
implicit parameter:Scala