Scala模式匹配

目录

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 = 3
		val b = 2
		val operator = "&"
		
		val result = operator match {
			case "+" => a + b
			case "-" => a - b
			case "*" => a * b
			case "/" => a.toDouble / b
			case _ => "illegal"
		}
		
		println(result)// illegal

2 模式守卫

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

3 模式匹配类型

3.1 匹配常量

匹配常量是模式匹配的一种形式,可以用于匹配特定的常量值。

val x = 1

x 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)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值