Scala学习笔记17: Try与异常处理

目录

    • [第十七章 Try与异常处理](#第十七章 Try与异常处理)
      • [1- 异常的抛出和捕获](#1- 异常的抛出和捕获)
        • [1. 异常抛出](#1. 异常抛出)
        • [2. 异常捕获](#2. 异常捕获)
      • [2- 函数式的错误处理](#2- 函数式的错误处理)
        • [1. `Try` 类型](#1. Try 类型)
        • [2. 使用 `Try`](#2. 使用 Try)
        • [3. 处理 `Try` 结果](#3. 处理 Try 结果)
        • [4. `Try` 的常用方法](#4. Try 的常用方法)
        • [5. `Try` 的优势](#5. Try 的优势)
        • 总结
      • end

第十七章 Try与异常处理

1- 异常的抛出和捕获

Scala 的异常处理机制与 Java非常相似, 但也有一些区别 ;

1. 异常抛出
  • Scala 使用 throw 关键字抛出异常, 和 Java一样 ;
  • Scala 没有"受检异常" (checked Exception) 的概念 ; 不需要声明函数可能抛出的异常 ;

示例:

scala 复制代码
  def divide(a: Int, b: Int): Int = {
    if (b == 0) {
      throw new IllegalArgumentException("Divisor cannot be zero!!!")
    }
    a / b
  }
scala 复制代码
  def main(args: Array[String]): Unit = {
    val res = divide(10, 0)
    println(res) // Output: java.lang.IllegalArgumentException: Divisor cannot be zero!!!
  }
2. 异常捕获
  • Scala使用 try...catch...finally 结构捕获异常, 与 Java 类似, 但 catch 部分使用模式匹配来处理不同类型的异常 ;
  • finally 子句是可选的, 用于执行无论是否发生异常都需要执行的代码, 例如关闭资源 ;

示例:

scala 复制代码
  def divide(a: Int, b: Int): Int = {
    if (b == 0) {
      throw new IllegalArgumentException("Divisor cannot be zero!!!")
    }
    a / b
  }
scala 复制代码
    try {
      val res = divide(10, 0)
      println(res)
    } catch {
      case e: IllegalArgumentException => println(s"捕获到异常: ${e.getMessage}") // Output: 捕获到异常: Divisor cannot be zero!!!
    } finally {
      println("finally: 无论是否发生异常都会执行;") // Output: finally: 无论是否发生异常都会执行;
    }

说明:

  1. try块: 包含可能抛出异常的代码 ;
  2. catch块: 捕获异常; Scala的 catch 块是一个模式匹配的例子, 每个 case 分支处理不同类型的异常 ;
  3. finally块: 包含总是会执行的代码 (不管是否抛出异常) ; 通常用于释放资源, 如关闭文件或数据库连接 ;

Scala 的异常处理机制结合了 Java的 try...catch...finally 结构和自身的模式匹配, 提供了更灵活、更强大的异常处理能力 ;

同时, Try 类型为开发者提供了更函数式的异常处理方式, 使代码更简洁易懂 .

2- 函数式的错误处理

在Scala中, 函数式编程风格推崇使用不可变数据和纯函数, 尽量避免副作用和异常 ;但实际应用中, 异常难以完全避免 ;

Scala提供了 Try 类型, 让我们可以用更函数式的方法来处理异常 ;

1. Try 类型

Try 是 Scala中用于表示可能抛出异常的操作的结果类型 ; 它有两个子类:

  • Success[T] : 表示操作成功, 包含成功的结果值, 类型为 T ;
  • Failure[T] : 表示操作失败, 包含抛出的异常信息, 类型为 Throwable ;
2. 使用 Try

可以使用 Try 的伴生对象的 apply 方法将可能抛出异常的代码块包起来 :

示例:

scala 复制代码
    import scala.util.Try

    def riskyOperation(x: Int): Int = {
      if (x < 0) {
        throw new IllegalArgumentException("x must be positive")
      } else x * 2
    }

    val result: Try[Int] = Try(riskyOperation(-1))
    println(result) // Output: Failure(java.lang.IllegalArgumentException: x must be positive)
    
    val result2: Try[Int] = Try(riskyOperation(5))
    println(result2) // Output: Success(10)
3. 处理 Try 结果

可以用模式匹配的方式处理 Try 的结果:

scala 复制代码
    import scala.util.{Try, Success, Failure}

    def riskyOperation(x: Int): Int = {
      if (x < 0) {
        throw new IllegalArgumentException("x must be positive")
      } else x * 2
    }

    val result1: Try[Int] = Try(riskyOperation(-1))
    result1 match {
      case Success(value) => println(s"Success: $value")
      case Failure(exception) => println(s"Failure: ${exception.getMessage}")
    }
    // Output: Failure: x must be positive

    val result2: Try[Int] = Try(riskyOperation(5))
    result2 match {
      case Success(value) => println(s"Success: $value")
      case Failure(exception) => println(s"Failure: ${exception.getMessage}")
    }
    // Output: Success: 10
4. Try 的常用方法

Try 提供了一些方便地方法来处理异常, 例如:

  • map : 如果 TrySuccess , 则对成功的结果值应用函数, 并返回新的 Try ; 如果是 Failure , 则直接返回 Failure ;
  • flatMap : 与 map 类似, 但函数需要返回一个 Try 类型的值 ;
  • recover : 如果 TryFailure , 则应用偏函数来处理异常, 并返回新的 Try ; 如果是 Success , 则直接返回 Success ;
  • getOrElse : 如果 TrySuccess, 则返回成功的结果值; 如果是 Failure, 则返回默认值 ;
5. Try 的优势
  • 避免 try...catch 语句的嵌套, 使代码更简洁易读 ;
  • 将异常处理融入函数式编程风格, 可以使用 mapflatMap 等高阶函数 ;
  • 更容易组合和传递可能抛出异常的操作的结果 ;
总结

Try 类型是 Scala中函数式异常处理的重要工具, 它让挖煤可以用更优雅、更简洁的方式来处理异常, 使代码更易于理解和维护 .

end

相关推荐
LuH11247 分钟前
【论文阅读笔记】Learning to sample
论文阅读·笔记·图形渲染·点云
兔C12 分钟前
微信小程序的轮播图学习报告
学习·微信小程序·小程序
海海不掉头发19 分钟前
苍穹外卖-day05redis 缓存的学习
学习·缓存
小木_.1 小时前
【Python 图片下载器】一款专门为爬虫制作的图片下载器,多线程下载,速度快,支持续传/图片缩放/图片压缩/图片转换
爬虫·python·学习·分享·批量下载·图片下载器
一棵开花的树,枝芽无限靠近你1 小时前
【PPTist】组件结构设计、主题切换
前端·笔记·学习·编辑器
犬余2 小时前
设计模式之桥接模式:抽象与实现之间的分离艺术
笔记·学习·设计模式·桥接模式
啊瞑3 小时前
学习记录:配置mybatisplus的分页查询插件,mybatis-plus-jsqlparser 依赖
学习
码到成龚3 小时前
SQL server学习09-数据库编程(上)
数据库·学习
数据爬坡ing3 小时前
小白考研历程:跌跌撞撞,起起伏伏,五个月备战历程!!!
大数据·笔记·考研·数据分析
咖肥猫3 小时前
【ue5学习笔记2】在场景放入一个物体的蓝图输入事件无效?
笔记·学习·ue5