目录
1 基本用法
2 模式守卫
3 模式匹配类型
3.1 匹配常量
3.2 匹配类型
3.3 匹配数组
3.4 匹配列表
3.5 匹配元组
4 匹配对象及样例类
4.1 匹配对象
4.2 样例类
5 变量声明中的模式匹配
6 for 表达式中的模式匹配
7 偏函数中的模式匹配(了解)
7.1 偏函数概念
7.2 偏函数定义
7.3 偏函数原理
7.4 偏函数使用
在 Scala 中,模式匹配是一种强大的语言特性,它可以用于匹配各种类型的值,包括基本类型、集合、对象等,从而实现分支逻辑、类型转换、提取数据等操作。
val a = 3val b = 2val operator = "&"val result = operator match {case "+" => a + bcase "-" => a - bcase "*" => a * bcase "/" => a.toDouble / bcase _ => "illegal"}println(result)// illegal
def abs(x: Int) = x match {case i: Int if i >= 0 => icase j: Int if j < 0 => -jcase _ => "type illegal"}println(abs(-1))
匹配常量是模式匹配的一种形式,可以用于匹配特定的常量值。
val x = 1x match {case 1 => println("x is one")case 2 => println("x is two")case _ => println("x is neither one nor two")
}
Scala的模式匹配功能还可以用于匹配类型。这意味着您可以根据表达式的类型来执行不同的代码块。
def process(input: Any): Unit = {input match {case x: Int => println(s"$x is an integer")case s: String => println(s"$s is a string")case d: Double => println(s"$d is a double")case _ => println("Unknown type")}
}process(42) // 42 is an integer
process("hello") // hello is a string
process(3.14) // 3.14 is a double
process(true) // Unknown type
val arr = Array("apple", "banana", "orange")arr match {case Array() => println("empty array")case Array(x) => println(s"one-element array: $x")case Array("apple", "banana", _*) => println("starts with apple and banana")case _ => println("something else")
}
val lst = List(1, 2, 3)lst match {case Nil => println("empty list")case x :: Nil => println(s"one-element list: $x")case 1 :: 2 :: 3 :: _ => println("starts with 1, 2, 3")case _ => println("something else")
}
val tup = (1, "hello", 3.14)tup match {case (1, _, _) => println("starts with 1")case (_, "hello", _) => println("second element is hello")case (_, _, d) if d > 0.0 => println("third element is positive")case _ => println("something else")
}
case class Person(name: String, age: Int) {}object TestMatch extends App {val alice = Person("Alice", 25)val bob = Person("Bob", 30)def process(person: Person): Unit = {person match {case Person("Alice", _) => println("Hi Alice!")case Person("Bob", age) if age > 25 => println("Hi Bob, you are over 25!")case Person(name, _) => println(s"Hi $name, how are you?")case _ => println("Unknown person")}}process(alice) // Hi Alice!process(bob) // Hi Bob, you are over 25!process(Person("Charlie", 35)) // Hi Charlie, how are you?
}
在Scala中,样例类(case class)是一种特殊的类,它具有以下特点:
apply
方法:样例类自动带有一个apply
方法,可以用于创建该类的对象,而无需使用new
关键字。unapply
方法:样例类自动带有一个unapply
方法,可以用于提取该类的属性值。equals
和hashCode
方法:样例类自动实现了equals
和hashCode
方法,可以用于比较两个对象是否相等。toString
方法:样例类自动实现了toString
方法,可以用于打印该类的对象。样例类通常用于表示不可变的数据,例如,一张纸牌、一条消息或一个人的信息等。它们提供了一种简洁而直观的方式来表示这些数据,并且可以方便地进行模式匹配。
以下是一个样例类的示例:
case class Person(name: String, age: Int)
val (x, y) = (1, 2)
可以使用模式匹配来解构一个元组,或者匹配一个列表的头和尾。下面是一个例子:
val (head :: tail) = List(1, 2, 3)// 1
// List(2, 3)
在 Scala 的
for
表达式中,可以使用模式匹配来解构集合中的元素。这种方式可以让我们在遍历集合的同时,对集合中的元素进行匹配和赋值。
val list = List((1, "one"), (2, "two"), (3, "three"))
for ((num, word) <- list) {println(s"$num is written as $word")
}
偏函数也是函数的一种,通过偏函数我们可以方便的对输入参数做更精确的检查。例如该偏函数的输入类型为List[Int],而我们需要的是第一个元素是 0 的集合,这就是通过模式匹配实现的。
// 该偏函数的功能是返回输入的List 集合的第二个元素
val second: PartialFunction[List[Int], Option[Int]] = { case x :: y :: _ => Some(y)
}
上述代码会被 scala 编译器翻译成以下代码,与普通函数相比,只是多了一个用于参数检查的函数——isDefinedAt,其返回值类型为 Boolean
val second = new PartialFunction[List[Int], Option[Int]] {//检查输入参数是否合格override def isDefinedAt(list: List[Int]): Boolean = list match{case x :: y :: _ => true case _ => false}//执行函数逻辑override def apply(list: List[Int]): Option[Int] = list match{case x :: y :: _ => Some(y)}}
偏函数不能像 second(List(1,2,3))这样直接使用,因为这样会直接调用 apply 方法,而应该调用 applyOrElse 方法,如下
second.applyOrElse(List(1,2,3), (_: List[Int]) => None)
applyOrElse 方法的逻辑为
if (ifDefinedAt(list)) apply(list)
else default
如果输入参数满足条件,即 isDefinedAt 返回 true,则执行 apply 方法,否则执行 defalut 方法,default 方法为参数不满足要求的处理逻辑。
例如
将该List(1,2,3,4,5,6,"test")中的 Int 类型的元素加一,并去掉字符串。
list.collect { case x: Int => x + 1 }.foreach(println)
上一篇:新农具时代,拼多多的进击与本分
下一篇:java基础面试题(四)