目录
scala outline
scala match 代码示例
-
java模式匹配使用的关键字为switch-case,scala是match-case
-
每个 case 中,不用 break 语句,自动中断 case
-
如果所有case都不匹配,那么会执行case _ 分支,类似于Java中default语句,若此时没有case _ 分支,那么会抛出MatchError
-
=> 后面的代码块到下一个 case, 是作为一个整体执行,可以使用{} 括起来
def main(args: Array[String]): Unit = {
var a: Int = 10
var b: Int = 20
var op: Char = '+'
//模式匹配是有返回值
var res = op match {
case '+' => a + b
case '-' => a - b
case _ => "默认情况"
}
println(res)
}
scala 模式守卫
如果想要表达匹配某个范围的数据,
就需要在模式匹配中增加条件守卫
通过模式守卫 求一个整数的绝对值
def main(args: Array[String]): Unit = {
def abs(num: Int): Int = {
num match {
case x: Int if x >= 0 => x
case x: Int if x < 0 => -x
}
}
println(abs(-7))
}
scala 模式匹配
Scala中,模式匹配可以匹配所有的字面量,包括字符串,字符,数字,布尔值等等
def main(args: Array[String]): Unit = {
def f(e: Any): Any = {
e match {
case "hello" => "String"
case true => "Boolean"
case '+' => "op"
case 5 => "Int"
case _ => "默认情况"
}
}
println(f("hello"))
}
需要进行类型判断时,可以使用isInstanceOf[T]和asInstanceOf[T],也可使用模式匹配实现同样的功能
def main(args: Array[String]): Unit = {
def f(e: Any): Any = {
e match {
case s: String => "String"
case flag: Boolean => "Boolean"
case m: List[String] => "List"
case a: Array[Int] => "Array[Int]"
case d => "something else" + d
}
}
// 泛型擦除,在匹配的时候,和泛型无关(只限于集合,排除数组)
println(f(List(2, 3))) // 输出 List
}
3者之间非常类似,只演示匹配数组
val list = List(Array(0), Array("hello", 90), Array(0, 1, 0), Array(1, 1, 0))
for (arr <- list) {
val res: String = arr match {
case Array(0) => "0"
case Array(x, y) => x + "," + y
case Array(0, _*) => "以0开头的数组"
case _ => "something else"
}
println(res)
}
}
输出
0
hello,90
以0开头的数组
something else
object Test02 {
def main(args: Array[String]): Unit = {
val xiaoming: User = new User("老王", 55)
val res = xiaoming match {
case User("老王", 55) => "Yes" // 底层会调用unapply(),然后把小明作为参数传过去,获取小明的属性,然后会和老王进行比较
case _ => "NO"
}
println(res)
}
}
class User(var name: String, var age: Int) {}
object User {
// 根据属性创建对象(此处没有用)
def apply(name: String, age: Int): User = new User(name, age)
// 根据对象获取属性
def unapply(arg: User): Option[(String, Int)] = {
if (arg == null)
return None
else {
return Some(arg.name, arg.age)
}
}
}
可用case
关键字来简化上述代码,参考样例类
- 样例类
用 case 关键字进行声明
- 样例类仍然是类,和普通类相比,只是其自动生成了伴生对象,并且伴生对象中自动提供了一些常用的方法,如
apply、unapply、toString
、equals、hashCode和copy - 样例类是
为模式匹配而优化的类
,因为其默认提供了unapply方法,所以样例类可以直接使用模式匹配,而无需自己实现unapply方法 - 构造器中的每一个参数都成为val,除非它被显式地声明为var(不建议这样做)
参考匹配对象
object Test02 {
def main(args: Array[String]): Unit = {
val laowang: User = new User("老王", 55)
val res = laowang match {
case User("老王", 55) => "Yes"
case _ => "NO"
}
println(res) // Yes
}
}
case class User(var name: String, var age: Int) {}
两个元素间用::
叫中置表达式
def main(args: Array[String]): Unit = {
List(1, 3, 5, 9) match { //修改并测试
// 1.两个元素间::叫中置表达式,至少 first,second 两个匹配才行.
// 2.first 匹配第一个 second 匹配第二个, rest 匹配剩余部分(5,9)
case first :: second :: rest => println(first + " " + second + " " + rest) // 1 3 List(5, 9)
case _ => println("not match!")
}
}
scala case 简化小案例
实现wordcount
def main(args: Array[String]): Unit = {
val list: List[(String, Int)] = List(("a", 1), ("b", 2), ("c", 3))
val newList: List[(String, Int)] = list.map((t: (String, Int)) => {
t match {
case (word, count) => (word, count * 2)
}
})
println(newList) // 输出 List((a,2), (b,4), (c,6))
}
选中 部分是一个匿名函数,匿名函数可以简化
简化后的代码
- 如果一个函数参数的列表中只有一个参数,那么参数列表的小括号可以花括号代替
- 如果匿名函数中,使用模式匹配case,要求必须用花括号括起来
list.map { case (word, count) => (word, count * 2) }