当前位置: 首页 > news >正文

Scala学习笔记14: 模式匹配和样式类

目录

    • 第十四章 模式匹配和样式类
      • 1- 模式匹配
      • 2- 模式中的变量
      • 3- 类型模式
      • 4- 匹配数组、列表和元组等集合
      • 5- 样例类
      • 6- 守卫
      • 7- 提取器
      • 8- 变量声明中的模式
      • 9- for推导式中的模式
      • end

第十四章 模式匹配和样式类

在Scala中, 模式匹配和样例类是强大的功能, 用于处理复杂的数据结构和逻辑 ;

模式匹配是一种功能强大的机制, 可以根据数据的结构和属性进行匹配和处理 ;

样例类是一种特殊的类, 用于简化模式匹配和不可变性 .

1- 模式匹配

在Scala中, 模式匹配是一种强大的功能, 用于根据数据的结构和属性进行匹配和处理 ;

模式匹配类似于 switch 语句, 但更加灵活和功能丰富 ;

下面简单介绍Scala 中模式匹配的用法和特性 :

  1. 基本语法 :

    • Scala中的模式匹配使用 match 关键字, 结合 case 语句进行匹配

    • 示例:

    •     val x: Int = 2x match {case 1 => println("One")case 2 => println("Two")case _ => println("Other")}// 输出: Two
      
  2. 匹配类型 :

    • 可以根据数据类型进行匹配

    • 示例:

    •     // 匹配类型def matchType(x: Any): String = x match {case i: Int => s"Int: $i"case s: String => s"String: $s"case _ => "Other type"}println(matchType(1)) // 输出: Int: 1println(matchType("Hello")) // 输出: String: Helloprintln(matchType(true)) // 输出: Other type
      
  3. 匹配集合 :

    • 可以匹配集合中的元素

    • 示例:

    •     // 匹配集合val list = List(1, 2, 3, 4, 5)list match {case List(1, 2, 3, _, _) => println("List contains 1, 2, 3")case _ => println("Other list")}// 输出:List contains 1, 2, 3
      
  4. 匹配样例类 :

    • 可以使用样例类进行模式匹配

    • 示例:

    •     // 匹配样例类case class Person(name: String, age: Int)val person = Person("Tom", 18)val result = person match {case Person("Tom", 18) => "Tom is 18 years old"case _ => "unknown"}println(result) // 输出: Tom is 18 years oldval result2 = person match {case Person(name, age) => s"$name is $age years old"case _ => "unknown"}println(result2) // 输出: Tom is 18 years old
      
  5. 模式守卫 :

    • 可以使用模式守卫 (pattern guards) 对匹配条件进行进一步的限制 ;

    • 示例:

    •     // 模式守卫val x: Int = 10val y = x match {case i if i > 5 => "bigger than 5"case i if i < 5 => "smaller than 5"case _ => "equal to 5"}println(y) // Output: bigger than 5val z = x match {case even if even % 2 == 0 => "even"case odd if odd % 2 != 0 => "odd"case _ => "neither even nor odd"}println(s"$x is $z!") // Output: 10 is even!
      

通过模式匹配, 你可以根据不同的情况处理数据, 使代码更加清晰和易于理解 ;

模式匹配是Scala中强大且常用的功能之一, 适用于各种场景下的数据处理和逻辑判断 .

2- 模式中的变量

在Scala模式中, 变量模式 (Variable pattern) 是一种特殊的模式, 用于捕获匹配的值并将其绑定到变量上 ;

变量模式以小写字母开头, 可以在模式匹配中使用, 允许在匹配成功时将匹配的值赋值给变量 ;

如果关键字 case 后面跟着一个变量名, 那么匹配的表达式会被赋值给变量 ;

  1. 基本语法 :

    • 变量模式以小写字母开头, 用于捕获匹配的值 ;

    • 示例 :

    •     val x: Int = 22x match {case y => println(s"匹配到的值为: $y")}// Output: 匹配到的值为: 22
      
  2. 变量绑定 :

    • 变量模式还可以用于将匹配的值绑定到变量上, 以便后续使用 ;

    • 示例 :

    •     val x: Int = 6val result = x match {case z => z * 2}println(result) // Output: 12
      
  3. 使用场景 :

    • 变量模式适用于需要在模式匹配中捕获值并进行处理的情况 ;
    • 可以在模式匹配中使用变量模式来提取匹配值, 然后根据需要进行进一步的操作 ;

通过使用变量模式, 你可以在Scala模式匹配中灵活地捕获匹配的值并进行处理, 使得代码更加清晰和易于理解 ;

变量模式是模式匹配中常用且有用的一种模式, 适用于各种需要对匹配值进行操作的场景 .

3- 类型模式

在Scala中, 类型模式(type pattern) 是一种模式匹配的方式, 用于匹配特定的数据类型 ;

类型模式允许你根据数据的类型进行匹配, 并执行相应的操作 ;

  1. 基本语法 :

    • 类型模式用于匹配特定的数据类型, 通常与 case 语句结合使用 ;

    • 示例 :

    •     // 类型匹配def matchType(x: Any) = x match {case i: Int => s"int: $i"case s: String => s"string $s"case _ => "other"}println(matchType(1)) // int: 1println(matchType("a")) // string aprintln(matchType(true)) // otherprintln(matchType(List(1, 2, 3))) // other
      
  2. 使用场景 :

    • 类型模式适用于需要根据数据类型进行不同处理的情况 ;
    • 可以根据数据的类型来选择不同的逻辑分支, 实现更灵活的数据处理 ;
  3. 类型擦除 :

    • 在Scala中, 由于类型擦除的存在, 有时候无法直接匹配泛型类型 ;
    • 可以使用类型擦除后的类型进行匹配, 或者通过 ClassTag 等方式来处理泛型类型 ;

通过使用类型模式, 你可以根据数据的类型进行精确的匹配和处理, 使得代码更加灵活和具有表现力 ;

类型模式是Scala模式匹配中常用的一种模式, 适用于需要根据数据类型进行不同处理的各种场景 .

4- 匹配数组、列表和元组等集合

在Scala中, 模式匹配可以用于匹配数组、列表和元组等集合类型 ;

  1. 匹配数组 :

    • 使用 Array 类型进行匹配 ;

    • 示例:

    •     // 匹配数组val arr = Array(1, 2, 3, 4, 5)val result = arr match {case Array(1, _, _, _, _) => "匹配到数组的第一个元素为1"case Array(_, 2, _, _, _) => "匹配到数组的第二个元素为2"case Array(_, _, 3, _, _) => "匹配到数组的第三个元素为3"case Array(_, _, _, 4, _) => "匹配到数组的第四个元素为4"case Array(_, _, _, _, 5) => "匹配到数组的第五个元素为5"}println(result) // Output: 匹配到数组的第一个元素为1val result2 = arr match {case Array(1, 2, 3, 4, 5) => "匹配到数组[1, 2, 3]"case _ => "其它数组"}println(result2) // Output: 匹配到数组[1, 2, 3]
      
  2. 匹配列表 :

    • 使用 List 类型进行匹配 ;

    • 示例:

    •     // 匹配列表val list = List(1, 2, 3, 4, 5)list match {case List(1, 2, 3, 4, 5) => println("匹配成功, 列表[1, 2, 3, 4, 5]")case _ => println("匹配失败")}// Output: 匹配成功, 列表[1, 2, 3, 4, 5]
      
  3. 匹配元组 :

    • 使用元组类型进行匹配 ;

    • 示例 :

    •     // 匹配元组val t1 = (1, "a", 3.14, "π")t1 match {case (1, "a", 3.14, "π") => println("匹配到元组(1, \"a\", 3.14, \"π\")")case _ => println("其它元组")}// Output: 匹配到元组(1, "a", 3.14, "π")val t = (1, 2, "v")t match {case (a, b, c) => println(a + b + c)case _ => println("default")}// Output: 3v
      

通过以上示例, 你可以看到如何在Scala中使用模式匹配类匹配数组、列表和元组等集合类型 ;

模式匹配是Scala中强大且灵活的特性, 可以帮助你根据不同的数据结构进行精确的匹配和处理 .

5- 样例类

在Scala中 , 样例类 (case class) 是一种特殊的类, 用于表示不可变的数据结构 ;

样例类具有许多有用的特性, 使其在模式匹配和不可变数据建模方面非常有用 ;

  1. 定义样例类 :

    • 样例类使用 case class 关键字进行定义, 通常用于表示数据结构 ;

    • 示例 :

    • case class Person(name: String, age: Int)
      
  2. 特性 :

    • 样例类自动提供了 equalshashCodetoString 方法的实现 ;
    • 样例类的构造器参数默认是 val , 使其成为不可变的数据结构 ;
    • 可以使用模式匹配类处理样例类的实例 ;
  3. 模式匹配 :

    • 样例类子啊模式匹配中非常有用, 可以根据不同的样例类进行不同的处理 ;

    • 示例 :

    •     // 样例类 模式匹配case class Person(name: String, age: Int)val person = Person("zhangsan", 18)val result = person match {case Person("zhangsan", 18) => "zhangsan is 18"case Person("zhangsan", 19) => "zhangsan is 19"case _ => "other"}println(result) // Output: zhangsan is 18val result2 = person match {case Person(name, age) => s"$name is $age"case _ => "other"}println(result2) // Output: zhangsan is 18
      
  4. 不可变性 :

    • 样例类的实例时不可变的, 这意味着一旦创建就无法更改其内容 ;
    • 这种不可变性使得样例类在函数式编程和数据建模中非常有用 ;

通过使用样例类, 你可以轻松地表示不可变的数据结构, 并利用Scala强大的模式匹配功能来处理这些数据 ;

样例类是Scala中常用的概念, 用于简化数据建模和模式匹配的过程 .

6- 守卫

在Scala中, 模式匹配中的守卫 (guards) 是一种强大的机制, 允许在 scae 语句中添加布尔表达式作为额外条件, 以进一步细化匹配的逻辑 ;

当模式匹配遇到带有守卫的 case 语句时, 只有当守卫条件为真时, 才会执行该 case 语句 ;

这使得模式匹配更加灵活, 能够根据特定条件选择不同的分支逻辑 ;

  1. 基本语法 :

    • 守卫是在 case 语句后使用 if 关键字加上布尔表达式来定义的 ;

    • 示例 :

    •     val a: Int = 12a match {case even if a % 2 == 0 => println(s"$even 是偶数")case odd if a % 2 == 1 =>  println(s"$odd 是奇数")}// Output: 12 是偶数
      
  2. 使用场景 :

    • 守卫允许根据更复杂的条件进行模式匹配, 例如数值的特定属性或范围 ;
    • 可以在模式匹配中结合守卫实现更精细的逻辑控制, 避免冗长的嵌套 if-else 语句 ;
  3. 灵活性 :

    • 守卫条件可以是任何布尔表达式, 可以包含逻辑运算、比较操作等 ;
    • 守卫使得模式匹配更具表现力和可读性, 能够处理更多复杂的匹配情况 ;

通过使用守卫, 你可以根据额外的条件对模式匹配进行细致化的控制, 使得代码更加清晰和易于维护 ;

守卫是Scala模式匹配中的重要特性 , 为处理各种匹配情况提供了更多的灵活性和表达能力 .

7- 提取器

在Scala中, 提取器 (Extractor) 是一种用于模式匹配的对象, 它定义了从输入中提取出构造参数的逻辑;

提取器通常用于将对象分解为其组成部分, 以便在模式匹配中使用 ;

提取器对象必须包含 unapply 方法, 用于从输入中提取值 ;

  1. 基本语法 :

    • 提取器对象通常包含 unapply 方法, 用于提取值并返回一个 Option 类型的结果 ;

    • 示例 :

    •     object Email {def unapply(email: String): Option[(String, String)] = {val parts = email.split("@")if (parts.length == 2) {Some(parts(0), parts(1))} else {None}}}val email = "zhangsan@163.com"val Email(name, domain) = emailprintln(name) // Output: zhangsanprintln(domain) // Output: 163.com
      
  2. 模式匹配中的应用 :

    • 提取器通常与模式匹配结合使用, 允许从对象中提取数据并进行匹配 ;

    • 示例 :

    •     object Email {def unapply(email: String): Option[(String, String)] = {val parts = email.split("@")if (parts.length == 2) {Some(parts(0), parts(1))} else {None}}}// 模式匹配中使用 提取器val email = "john.doe@gmail.com"email match {case Email(name, domain) => println(s"Name: $name, Domain: $domain")case _ => println("Invalid email format!")}// Output: Name: john.doe, Domain: gmail.com
      
  3. 提取器对象 :

    • 提取器对象可以定义多个 unapply 方法重载, 以适应不同的匹配情况 ;
    • 提取器对象还可定义 unapplySeq 方法用于提取序列类型的值 ;

通过使用提取器, 你可以在Scala中更加灵活地进行模式匹配, 从复杂的数据结构中提取所需的信息 ;

提取器是Scala模式匹配的重要组成部分, 使得代码更具表现力和可读性 .

8- 变量声明中的模式

在Scala中, 变量声明中的模式 (pattern) 允许你在声明变量时使用模式匹配的方式 ;

这种模式匹配的变量声明方式可以帮助你从复杂的数据结构中提取所需的部分, 并将其赋值给变量 ;

  1. 基本语法 :

    • 在变量声明时, 可以使用模式匹配的方式来提取数据并赋值给变量 ;

    • 示例 :

    •     val (x, y) = (1, 2) // 将元组(1, 2) 赋值给变量 x, yprintln(x) // Output: 1println(y) // Output: 2
      
  2. 匹配复杂数据结构 :

    • 变量声明中的模式允许你从各种数据结构中提取数据, 如元组、列表、样例类等 ;

    • 示例 :

    •     val List(a, b, c) = List(1, 2, 3)println(a) // Output: 1println(b) // Output: 2println(c) // Output: 3
      
  3. 匹配嵌套结构 :

    • 可以在变量声明中使用模式匹配来处理嵌套的数据结构, 如元组中包含元组的情况 ;

    • 示例 :

    •     val ((x, y), z) = ((1, 2), 3) // 从嵌套的元组中提取值并赋给变量 x y zprintln(x) // Output: 1println(y) // Output: 2println(z) // Output: 3
      

通过在变量声明中使用模式, 你可以更加灵活地从数据结构中提取所需的部分, 并将其赋值给变量, 使得代码更具表现力和简洁性 ;

这种模式匹配的变量声明方式在处理复杂数据结构时非常有用 .

9- for推导式中的模式

在Scala中, for 推导式中的模式匹配是一种强大的功能, 允许你在遍历集合或序列时使用模式匹配来接受元素并提取所需的部分 ;

  1. 基本语法 :

    • for 推导式中, 可以使用模式匹配来接受集合中的元素, 并将匹配的部分赋值给变量 ;

    • 示例 :

    •     val list = List((1, "one"), (2, "two"), (3, "three"))for (elem <- list) {val (num, str) = elemprintln(s"num: $num, str: $str")}/*num: 1, str: onenum: 2, str: twonum: 3, str: three*/
      
  2. 匹配嵌套结构 :

    • 你可以在 for 推到式中使用模式匹配来处理嵌套的数据结构, 如元组中包含元组的情况 ;

    • 示例 :

    •     val nestList = List((1, "one", true), (2, "two", false), (3, "three", true))for ((num, str, bool) <- nestList) {println(s"Number: $num, Name: $str, Flage: $bool")}/*Number: 1, Name: one, Flage: trueNumber: 2, Name: two, Flage: falseNumber: 3, Name: three, Flage: true*/
      
  3. 过滤条件 :

    • 可以结合模式匹配和条件表达式来过滤元素, 只处理符合条件的部分 ;

    • 示例 :

    •     val nestList = List((1, "one", true), (2, "two", false), (3, "three", true))for ((num, str, bool) <- nestList if bool == true) {println(s"Number: $num, Name: $str, Flage: $bool")}/*Number: 1, Name: one, Flage: trueNumber: 3, Name: three, Flage: true*/
      

通过在 for 推导式中使用模式匹配, 可以更加灵活地处理集合中的元素, 从而简化代码并提高可读性 ;

模式匹配在 for 循环中的应用使得处理复杂数据结构变得更加方便和直观 .

end

相关文章:

  • 酷瓜云课堂(内网版)v1.1.5 发布,局域网在线学习+考试系统
  • 5步快速了解电商渠道数字化管理||电商API数据采集|数据分析
  • Redis—List数据类型及其常用命令详解
  • 甘肃的千层烤馍:传统面点的魅力绽放
  • Flutter showModalBottomSheet用法
  • 粘包拆包服务器
  • openssl 命令行生成密钥对,生成hash,PSS填充签名,校验
  • x64汇编fastcall调用约定
  • 高阶图神经网络 (HOGNN) 的概念、分类和比较
  • 每月 GitHub 探索|10 款引领科技趋势的开源项目
  • 数学-奇异值
  • STM32通过SPI硬件读写W25Q64
  • MFC GDI绘制卡通人物
  • 长亭网络通信基础
  • LabVIEW、Matlab与Python的比较:从多角度详解三大编程工具
  • __proto__ 和 prototype的关系
  • egg(89)--egg之redis的发布和订阅
  • ES6简单总结(搭配简单的讲解和小案例)
  • Git的一些常用操作
  • JS实现简单的MVC模式开发小游戏
  • miniui datagrid 的客户端分页解决方案 - CS结合
  • session共享问题解决方案
  • SpringBoot几种定时任务的实现方式
  • Vue 2.3、2.4 知识点小结
  • Vue 重置组件到初始状态
  • windows下使用nginx调试简介
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 计算机在识别图像时“看到”了什么?
  • 技术发展面试
  • 聊聊hikari连接池的leakDetectionThreshold
  • 配置 PM2 实现代码自动发布
  • 前端设计模式
  • 浅谈Golang中select的用法
  • 如何设计一个比特币钱包服务
  • 手写双向链表LinkedList的几个常用功能
  • 微信小程序填坑清单
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • 3月27日云栖精选夜读 | 从 “城市大脑”实践,瞭望未来城市源起 ...
  • puppet连载22:define用法
  • 函数计算新功能-----支持C#函数
  • ​zookeeper集群配置与启动
  • ​一些不规范的GTID使用场景
  • # Redis 入门到精通(七)-- redis 删除策略
  • #我与Java虚拟机的故事#连载13:有这本书就够了
  • $L^p$ 调和函数恒为零
  • (1)(1.13) SiK无线电高级配置(六)
  • (1)Android开发优化---------UI优化
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (2)(2.4) TerraRanger Tower/Tower EVO(360度)
  • (2.2w字)前端单元测试之Jest详解篇
  • (21)起落架/可伸缩相机支架
  • (rabbitmq的高级特性)消息可靠性
  • (六)Flink 窗口计算
  • (完整代码)R语言中利用SVM-RFE机器学习算法筛选关键因子
  • (微服务实战)预付卡平台支付交易系统卡充值业务流程设计