高级特性
原创大约 4 分钟
模式匹配
Scala 2虽然没有Java那样的switch case
语法,但提供了match case
,即模式匹配
。
一般模式匹配
match case
可以匹配各种场景,例如变量的类型、集合中的元素、是否为空值等。
package com.itechthink
import java.io._
import scala.io.Source.fromFile
/**
* 模式匹配
*
*/
object PatternMatch {
/**
* 匹配常量
*
*/
private def demo1(day: Int): Unit = {
day match {
case 1 => println("星期一")
case 2 => println("星期二")
case 3 => println("星期三")
case 4 => println("星期四")
case 5 => println("星期五")
case 6 => println("星期六")
case 7 => println("星期日")
case _ => println("输入错误")
}
}
/**
* 变量类型的模式匹配
*
*/
private def demo2(x: Any): Unit = {
x match {
case i: Int => println("Int")
case s: String => println("String")
case _ => println("其他")
}
}
/**
* 匹配异常
*
*/
private def readFile(): Unit = {
try {
// 读取一个不存在的文件
val lines = fromFile("/Users/bear/Downloads/scala111.txt").mkString
} catch {
case e1: FileNotFoundException => println("FileNotFoundException:" + e1)
case e2: IOException => println("IOException:" + e2)
case _: Exception => println("Exception")
}
}
def main(args: Array[String]): Unit = {
demo1(3)
demo2("3")
readFile()
}
}
case class
除了这些,Scala 2还提供了case class
,也叫样例类
。它类似于Java中的JavaBean
,它只需要定义成员变量,Scala 2会自动提供它的getter
和setter
方法。
case class
的主构造函数接收的参数不需要var
或val
修饰,Scala 2会自动使用val
修饰它们。
Scala 2也会自动为case class
定义伴生对象
和apply()
方法,它接收主构造函数中相同的参数并返回case class
对象。
package com.itechthink
/**
* case class
*
*/
object CaseClass {
/**
* 匹配异常
*
*/
private def check(person: Person): Unit = {
person match {
case Teacher(name, subject) => println("Teacher name = " + name + ",subject = " + subject)
case Student(name, grade) => println("Student name = " + name + ",grade = " + grade)
case _ => println("Unknown")
}
}
def main(args: Array[String]): Unit = {
// 因为会自动创建apply()方法,所以可以直接使用Teacher(),而不用new
check(Teacher("李星云", "武术"))
check(Student("王林", "一年级"))
check(new Person)
}
}
class Person
case class Teacher(name: String, subject: String) extends Person
case class Student(name: String, grade: String) extends Person
Option
Scala 2有一种特殊的数据类型,称为Option
,它只有两个值。
Some
:表示有值。None
:表示无值。
Option
用于模式匹配
中判断变量是否有值。
scala> val users = Map("lixingyun" -> 20, "wanglin" -> 22)
users: scala.collection.immutable.Map[String,Int] = Map(lixingyun -> 20, wanglin -> 22)
scala> users("lixingyun")
res0: Int = 20
scala> users.get("lixingyun")
res1: Option[Int] = Some(20)
// 读取一个不存在的值
scala> users.get("xiaoyan")
res2: Option[Int] = None
开发时是这样用的。
package com.itechthink
/**
* Option Case
*
*/
object OptionCase {
private val users = Map("lixingyun" -> 20, "wanglin" -> 22)
private def getUser(name: String): Unit = {
val option = users.get(name)
option match {
case Some(age) => println(age)
case None => println("没有这个人")
}
}
def main(args: Array[String]): Unit = {
getUser("lixingyun")
getUser("xiaoyan")
}
}
隐式转换
Scala 2的隐式转换
允许手动将某种类型的对象转换成其他类型的对象。
它需要开发者自己用implicit function
语法来定义隐式转换函数
,而且要定义函数的返回类型。
Scala 2默认会使用两种隐式转换
。
源类型或者目标类型的伴生对象中的隐式转换函数。
当前程序作用域内可以用唯一标识符表示的隐式转换函数。
如果都不属于以上情况,那么就必须手动使用import
语法导入某个包下的隐式转换函数
。
package com.itechthink
/**
* implicit conversion
*
*/
object ImplicitConversion {
/**
* 狗拿耗子
*
*/
implicit def object2Cat(obj: Object): Cat = {
if (obj.getClass == classOf[Dog]) {
val dog = obj.asInstanceOf[Dog]
new Cat(dog.name)
} else {
null
}
}
def main(args: Array[String]): Unit = {
val dog = new Dog("小黄狗")
val pig = new Pig("小黑猪")
dog.eatBone()
pig.eat()
// 这里并没有显式调用任何类型转换方法
dog.catchMouse()
// 调用到这里会报错:NullPointerException
pig.catchMouse()
}
}
// 猫抓老鼠
class Cat(val name: String) {
def catchMouse() {
println(name + " 抓只一只大老鼠")
}
}
// 狗吃骨头
class Dog(val name: String) {
def eatBone() {
println(name + " 吃了一根骨头")
}
}
// 猪吃糠
class Pig(val name: String) {
def eat() {
println(name + " 正在吃糠")
}
}
大部分情况下都不需要自己定义隐式转换函数
,只需要导入某个包下的隐式转换函数
就行了,但知道它的工作机制是必要的。
感谢支持
更多内容,请移步《超级个体》。