Scala模式匹配

目录

1.scala模式匹配形式

这是java的switch语法

scala的模式匹配(现阶段的java中也支持=>的写法了)写法:

2.基本语法

模式匹配注意点情况说明:

3.模式守卫

 4.匹配类型:

5.匹配数组:

6.匹配列表

 7.匹配元组

8.匹配对象以及样例类

样例类:

9.变量声明中的模式匹配

10.for表达式中的模式匹配

11.偏函数中的模式匹配


1.scala模式匹配形式

scala的模式匹配类似于java中的switch语法

这是java的switch语法

Scala模式匹配_第1张图片

scala的模式匹配(现阶段的java中也支持=>的写法了)写法:

Scala模式匹配_第2张图片

2.基本语法

模式匹配语法中,采用 match 关键字声明,每个分支采用 case 关键字进行声明,当需 要匹配时,会从第一个 case 分支开始,如果匹配成功,那么执行对应的逻辑代码,如果匹 配不成功,继续执行下一个分支进行判断。如果所有 case 都不匹配,那么会执行 case _分支, 类似于 Java 中 default 语句。

模式匹配注意点情况说明:

(1)如果所有 case 都不匹配,那么会执行 case _ 分支,类似于 Java 中 default 语句, 若此时没有 case _ 分支,那么会抛出 MatchError。

(2)每个 case 中,不需要使用 break 语句,自动中断 case。

 (3)match case 语句可以匹配任何类型,而不只是字面量。

(4)=> 后面的代码块,直到下一个 case 语句之前的代码是作为一个整体执行,可以 使用{}括起来,也可以不括。

(5)每一个case条件成立才返回,否则继续往下走

6 模式匹配支持类型:所有类型字面量,包括字符串、字符、数字、布尔值、甚至数组列表等。

(7)你甚至可以传入Any类型变量,匹配不同类型常量。

(8)需要注意默认情况处理,case _也需要返回值,如果没有但是又没有匹配到,就抛出运行时错误。默认情况case _不强制要求通配符(只是在不需要变量的值建议这么做),也可以用case abc一个变量来接住,可以什么都不做,可以使用它的值。

(9)通过指定匹配变量的类型(用特定类型变量接住),可以匹配类型而不匹配值,也可以混用。

(10)需要注意类型匹配时由于泛型擦除,可能并不能严格匹配泛型的类型参数,编译器也会报警告。但Array是基本数据类型,对应于java的原生数组类型,能够匹配泛型类型参数。

3.模式守卫

如果想要表达匹配某个范围的数据,就需要在模式匹配中增加条件守卫

case匹配中可以添加模式守卫,用条件判断来代替精确匹配

Scala模式匹配_第3张图片

 4.匹配类型:

实例1:输入iint类型)时输出”int+i,输入sstring类型)时输出”string+s,输入List类型时输出”“List+listArray->array+array a->"something else"+a

Scala模式匹配_第4张图片

 对于数组可以定义多种匹配形式,可以定义模糊的元素类型匹配、元素数量匹配或者精确的某个数组元素值匹配,非常强大。 

5.匹配数组:

scala 模式匹配可以对集合进行精确的匹配,例如匹配只有两个元素的、且第一个元素 为 0 的数组。

实例2:依据元素个数进行模式匹配 

Scala模式匹配_第5张图片

6.匹配列表

List匹配和Array差不多,也很灵活。还可用用集合类灵活的运算符来匹配

      比如使用::运算符匹配first :: second :: rest,将一个列表拆成三份,第一个第二个元素和剩余元素构成的列表。

Scala模式匹配_第6张图片

Scala模式匹配_第7张图片

注意模式匹配不仅可以通过返回值当做表达式来用,也可以仅执行语句类似于传统

switch-case语句不关心返回值,也可以既执行语句同时也返回

 7.匹配元组

可以匹配n元组、匹配元素类型、匹配元素值。如果只关心某个元素,其他就可以用通配符或变量。

元组大小固定,所以不能用_*

指定特定元素的值,可以实现类似于循环守卫的功能,相当于加一层筛选。比如for ((10, second) <- tupleList)

元组列表匹配、赋值匹配、for循环中匹配非常灵活,灵活运用可以提高代码可读性。

Scala模式匹配_第8张图片

 拓展实例

Scala模式匹配_第9张图片

Scala模式匹配_第10张图片

8.匹配对象以及样例类

  对象内容匹配。

  直接match-case中匹配对应引用变量的话语法是有问题的。编译报错信息提示:   不是样例类也没有一个合法的unapply/unapplySeq成员实现。

  要匹配对象,需要实现伴生对象unapply方法,用来对对象属性进行拆解以做匹配。

基本语法:

Scala模式匹配_第11张图片

 小结:

➢ val user = User("zhangsan",11),该语句在执行时,实际调用的是 User 伴生对象中的

apply 方法,因此不用 new 关键字就能构造出相应的对象。

➢ 当将 User("zhangsan", 11)写在 case 后时[case User("zhangsan", 11) => "yes"],会默认调用 unapply 方法(对象提取器),user 作为 unapply 方法的参数,unapply 方法 将 user

对象的 name 和 age 属性提取出来,与 User("zhangsan", 11)中的属性值进行 匹配

➢ case 中对象的 unapply 方法(提取器)返回 Some,且所有属性均一致,才算匹配成功, 属性不一致,或返回 None,则匹配失败。

➢ 若只提取对象的一个属性,则提取器为 unapply(obj:Obj):Option[T] 若提取对象的多个属性,则提取器为 unapply(obj:Obj):Option[(T1,T2,T3…)] 若提取对象的可变个属性,则提取器为 unapplySeq(obj:Obj):Option[Seq[T]]

样例类:

第二种实现对象匹配的方式是样例类。

case class className定义样例类,会直接将打包apply和拆包unapply的方法直接定义好。

样例类定义中主构造参数列表中的val甚至都可以省略,如果是var的话则不能省略,最好加上的感觉,奇奇怪怪的各种边角简化。

  基础语法:

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

  说明:

 样例类仍然是类,和普通类相比,只是其自动生成了伴生对象,并且伴生对象中 自动

提供了一些常用的方法,如 apply、unapply、toString、equals、hashCode 和 copy

 样例类是为模式匹配而优化的类,因为其默认提供了 unapply 方法,因此,样例 类可

以直接使用模式匹配,而无需自己实现 unapply 方法。

构造器中的每一个参数都成为 val,除非它被显式地声明为 var(不建议这样做)

实例:

Scala模式匹配_第12张图片

9.变量声明中的模式匹配

Scala模式匹配_第13张图片

10.for表达式中的模式匹配

Scala模式匹配_第14张图片

11.偏函数中的模式匹配

偏函数是函数的一种,通过偏函数我们可以方便的对参数做出更精确的检查,例如

偏函数输入类型是List[Int],需要第一个元素是0的集合,也可以通过模式匹配实现的。

通过一个变量定义方式定义,PartialFunction的泛型类型中,前者是参数类型,后者是返回值类型。函数体中用一个case语句来进行模式匹配。上面例子返回输入的List集合中的第二个元素。

偏函数不能像 second(List(1,2,3))这样直接使用,因为这样会直接调用 apply 方法,而应

该调用 applyOrElse 方法,如下

applyOrElse 方法的逻辑为 if (ifDefinedAt(list)) apply(list) else default。如果输入参数满 足条件,即 isDefinedAt 返回 true,则执行 apply 方法,否则执行 defalut 方法,default 方

法 为参数不满足要求的处理逻辑。

一般一个偏函数只能处理输入的一部分场景,实际中往往需要定义多个偏函数用以组合使用。

实例1:

将该 List(1,2,3,4,5,6,"test")中的 Int 类型的元素加一,并去掉字符串。

Scala模式匹配_第15张图片

你可能感兴趣的:(scala,java,开发语言)