Scala模式匹配
迪丽瓦拉
2025-06-01 15:08:18
0

目录

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 中,模式匹配是一种强大的语言特性,它可以用于匹配各种类型的值,包括基本类型、集合、对象等,从而实现分支逻辑、类型转换、提取数据等操作。

1 基本用法

		val a = 3val b = 2val operator = "&"val result = operator match {case "+" => a + bcase "-" => a - bcase "*" => a * bcase "/" => a.toDouble / bcase _ => "illegal"}println(result)// illegal

2 模式守卫

		def abs(x: Int) = x match {case i: Int if i >= 0 => icase j: Int if j < 0 => -jcase _ => "type illegal"}println(abs(-1))

3 模式匹配类型

3.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")
}

3.2 匹配类型

        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

3.3 匹配数组

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")
}

3.4 匹配列表

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")
}

3.5 匹配元组

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")
}

4 匹配对象及样例类

4.1 匹配对象

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?
}

4.2 样例类

在Scala中,样例类(case class)是一种特殊的类,它具有以下特点:

  • 自动生成构造函数:样例类的构造函数是自动生成的,不需要手动编写。
  • 自动生成apply方法:样例类自动带有一个apply方法,可以用于创建该类的对象,而无需使用new关键字。
  • 自动生成unapply方法:样例类自动带有一个unapply方法,可以用于提取该类的属性值。
  • 自动生成equalshashCode方法:样例类自动实现了equalshashCode方法,可以用于比较两个对象是否相等。
  • 自动生成toString方法:样例类自动实现了toString方法,可以用于打印该类的对象。

        样例类通常用于表示不可变的数据,例如,一张纸牌、一条消息或一个人的信息等。它们提供了一种简洁而直观的方式来表示这些数据,并且可以方便地进行模式匹配。

以下是一个样例类的示例:

case class Person(name: String, age: Int)

5 变量声明中的模式匹配

val (x, y) = (1, 2)

可以使用模式匹配来解构一个元组,或者匹配一个列表的头和尾。下面是一个例子:

val (head :: tail) = List(1, 2, 3)// 1
// List(2, 3)

6 ​​​​​​​for 表达式中的模式匹配

在 Scala 的 for 表达式中,可以使用模式匹配来解构集合中的元素。这种方式可以让我们在遍历集合的同时,对集合中的元素进行匹配和赋值。

val list = List((1, "one"), (2, "two"), (3, "three"))
for ((num, word) <- list) {println(s"$num is written as $word")
}

7 ​​​​​​偏函数中的模式匹配(了解)

7.1 偏函数概念

        偏函数也是函数的一种,通过偏函数我们可以方便的对输入参数做更精确的检查。例如该偏函数的输入类型为List[Int],而我们需要的是第一个元素是 0 的集合,这就是通过模式匹配实现的。

7.2 偏函数定义 

// 该偏函数的功能是返回输入的List 集合的第二个元素
val second: PartialFunction[List[Int], Option[Int]] = { case x :: y :: _ => Some(y)
}

 7.3 偏函数原理

        上述代码会被 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)}}

 7.4 偏函数使用

        偏函数不能像 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)

相关内容