- 模式匹配
- 隐式转换
模式匹配,其实类似于Java中的switch case语法,即对一个值进行条件判断,然后针对不同的条件,进行不同的处理
不过Scala没有Java中的switch case语法,但是,Scala提供了更加强大的match case语法,就是这个模式匹配
Java的switch case仅能匹配变量的值,而Scala的match case可以匹配各种情况,比如:变量的类型、集合的元素,有值没值
对变量的值进行模式匹配
match case语法格式:变量 match { case 值 => 代码 }
如果值为下划线,则代表了不满足以上所有情况下的默认处理
def demo1(day: Int) {
day match {
case 1 => println("Monday")
case 2 => println("Tuesday")
case 3 => println("Wednesday")
case _ => println("none")
}
}
执行
scala> demo1(1)
Monday
scala> demo1(4)
none
注意:match case中,只要一个case分支满足并处理了,就不会继续判断下一个case分支了,这一点与Java不同,java的switch case需要用break停止向下执行
变量类型的模式匹配
Scala的模式匹配一个强大之处就在于,可以直接匹配类型,而不是值!!!这点是java的switch case绝对做不到的
语法格式:变量 match { case 变量: 类型 => 代码 }
典型的一个应用场景就是针对异常的处理
import java.io._
def processException(e: Exception) {
e match {
case e1: IllegalArgumentException => println("IllegalArgumentException " + e1)
case e2: FileNotFoundException => println("FileNotFoundException " + e2)
case e3: IOException => println("IOException " + e3)
case _: Exception => println("Exception " )
}
}
执行
scala> processException(new Exception())
Exception
在try-catch异常中的应用
try {
val lines02 = scala.io.Source.fromFile("D://test02.txt").mkString
} catch {
case ex: FileNotFoundException => println("no file")
case ex: IOException => println("io exception")
case ex: Exception => println("exception")
}
case class与模式匹配
Scala中提供了一种特殊的类,用case class进行声明,中文可以称为样例类
case class其实有点类似于Java中的JavaBean的概念
即只定义field,会由Scala在编译时自动提供get和set方法,但是没有其它的method
case class的主构造函数接收的参数通常不需要使用var或val修饰,Scala自动就会使用val修饰(但是如果你自己使用var修饰,那么还是会按照var来,在这用哪个区别都不大)
Scala自动为case class定义了伴生对象,也就是object,并且定义了apply()方法,该方法接收主构造函数中相同的参数,并返回case class对象
下面来看一个案例:
先定义三个class
class Person
case class Teacher(name: String, sub: String) extends Person
case class Student(name: String, cla: String) extends Person
def check(p: Person) {
p match {
case Teacher(name, sub) => println("Teacher, name is " + name + ", sub is " + sub)
case Student(name, cla) => println("Student, name is " + name + ", cla is " + cla)
case _ => println("none")
}
}
scala> check(new Student("tom","class1"))
Student, name is tom, cla is class1
scala> check(new Person())
none
Option与模式匹配
Scala有一种特殊的数据类型,叫做Option。
Option有两种值,一种是Some,表示有值,一种是None,表示没有值
Option通常会用于模式匹配中,用于判断某个变量是有值还是没有值,这比null来的更加简洁明了
val ages = Map("jack" -> 18, "tom" -> 30, "jessic" -> 27)
def getAge(name: String) {
val age = ages.get(name)
age match {
case Some(age) => println("your age is " + age)
case None => println("none")
}
}
scala> getAge("jack")
your age is 18
scala> getAge("hehe")
none
隐式转换
Scala的隐式转换,允许手动指定将某种类型的对象转换成其它类型的对象
Scala的隐式转换,最核心的就是定义隐式转换函数,即implicit conversion function
隐式转换函数与普通函数唯一的语法区别是要以implicit开头而且最好要定义函数返回类型
隐式转换非常强大的一个功能,就是可以在不知不觉中加强现有类型的功能。也就是说,我们可以为某个普通类定义一个加强类,并定义对应的隐式转换函数,这样我们在使用加强类里面的方法的时候,Scala会自动进行隐式转换,把普通类转换为加强类,然后再调用加强类中的方法
Scala默认会自动使用两种隐式转换
1:源类型,或者目标类型的伴生对象里面的隐式转换函数
2:当前程序作用域内可以用唯一标识符表示的隐式转换函数
如果隐式转换函数不在上述两种情况下的话,那么就必须手动使用import引入对应的隐式转换函数
通常建议,仅仅在需要进行隐式转换的地方,比如某个函数内,用import导入隐式转换函数,这样可以缩小隐式转换函数的作用域,避免不需要的隐式转换
class cat(val name: String){
def catchMouse(){println(name+" catch mouse")}
}
class dog(val name: String)
implicit def object2Cat (obj: Object): cat = {
if (obj.getClass == classOf[dog]) {
val dog = obj.asInstanceOf[dog]
new cat(dog.name)
}
else Nil
}
scala> val d = new dog("d1")
d: dog = dog@7f0e0db3
scala> d.catchMouse()
d1 catch mouse
我们后续在工作中一般很少需要我们自己去定义隐式转换函数,大部分的场景是我们只需要使用import导入对应的隐式转换函数就可以了