学习Scala:使用try-catch表达式处理异常
本文节选自Martin Odersky,Lex Spoon和Bill Venners所著,Regular翻译的《Programming in Scala》的第七章。Scala是一种针对 JVM 将函数和面向对象技术组合在一起的编程语言。
AD:
Scala的异常和许多其它语言的一样。代之用普通方式那样返回一个值,方法可以通过抛出一个异常中止。方法的调用者要么可以捕获并处理这个异常,或者也可以简单地中止掉,并把异常升级到调用者的调用者。异常可以就这么升级,一层层释放调用堆栈,直到某个方法处理了它或没有剩下其它的方法。
51CTO编辑推荐:Scala编程语言专题
抛出异常
异常的抛出看上去与Java的一模一样。首先创建一个异常对象然后用throw关键字抛出:
- throw new IllegalArgumentException
尽管可能感觉有些出乎意料,Scala里, throw也是有结果类型的表达式。下面举一个有关结果类型的例子:
- val half =
- if (n % 2 == 0)
- n / 2
- else
- throw new RuntimeException("n must be even")
这里发生的事情是,如果n是偶数,half将被初始化为n的一半。如果n不是偶数,那么在half能被初始化为任何值之前异常将被抛出。因此,无论怎么说,把抛出的异常当作任何类型的值都是安全的。任何使用从throw返回值的尝试都不会起作用,因此这样做无害。
从技术角度上来说,抛出异常的类型是Nothing。尽管throw不实际得出任何值,你还是可以把它当作表达式。这种小技巧或许看上去很怪异,但像在上面这样的例子里却常常很有用。if的一个分支计算值,另一个抛出异常并得出Nothing。整个if表达式的类型就是那个实际计算值的分支的类型。Nothing类型将在以后的11.3节中讨论。
捕获异常
用来捕获异常的语法展示在代码7.11中。选择catch子句这样的语法的原因是为了与Scala很重要的部分:模式匹配:pattern matching保持一致。模式匹配是一种很强大的特征,将在本章概述并在第十五章详述。
- import java.io.FileReader
- import java.io.FileNotFoundException
- import java.io.IOException
- try {
- val f = new FileReader("input.txt")
- // Use and close file
- } catch {
- case ex: FileNotFoundException => // Handle missing file
- case ex: IOException => // Handle other I/O error
- }
代码 7.11 Scala的try-catch子句
这个try-catch表达式的行为与其它语言中的异常处理一致。程序体被执行,如果抛出异常,每个catch子句依次被尝试。本例中,如果异常是FileNotFoundException,那么第一个子句将被执行。如果是IOException类型,第二个子句将被执行。如果都不是,那么try-catch将终结并把异常上升出去。
注意
你将很快发现与Java的一个差别是Scala里不需要你捕获检查异常:checked exception,或把它们声明在throws子句中。如果你愿意,可以用ATthrows标注声明一个throws子句,但这不是必需的。
finally子句
如果想让某些代码无论方法如何中止都要执行的话,可以把表达式放在finally子句里。如,你或许想让打开的文件即使是方法抛出异常退出也要确保被关闭。代码7.12展示了这个例子。
- import java.io.FileReader
- val file = openFile()
- try {
- // 使用文件
- } finally {
- file.close() // 确保关闭文件
- }
代码 7.12 Scala的try-finally子句
注意
代码7.12展示了确保非内存资源,如文件,套接字,或数据库链接被关闭的惯例方式。首先你获得了资源。然后你开始一个try代码块使用资源。最后,你在finally代码块中关闭资源。这种Scala里的惯例与在Java里的一样,然而,Scala里你还使用另一种被称为贷出模式:loan pattern的技巧更简洁地达到同样的目的。
生成值
和其它大多数Scala控制结构一样,try-catch-finally也产生值。如,代码7.13展示了如何尝试拆分URL,但如果URL格式错误就使用缺省值。结果是,如果没有异常抛出,则对应于try子句;如果抛出异常并被捕获,则对应于相应的catch子句。如果异常被抛出但没被捕获,表达式就没有返回值。由finally子句计算得到的值,如果有的话,被抛弃。通常finally子句做一些清理类型的工作如关闭文件;他们不应该改变在主函数体或try的catch子句中计算的值。
- import java.net.URL
- import java.net.MalformedURLException
- def urlFor(path: String) =
- try {
- new URL(path)
- } catch {
- case e: MalformedURLException =>
- new URL("http://www.scalalang.org")
- }
代码 7.13 能够产生值的catch子句
如果熟悉Java,不说你也知道,Scala的行为与Java的差别仅源于Java的try-finally不产生值。Java里,如果finally子句包含一个显式返回语句,或抛出一个异常,这个返回值或异常将“凌驾”于任何之前源于try代码块或某个它的catch子句产生的值或异常之上。如:
- def f(): Int = try { return 1 } finally { return 2 }
调用f()产生结果值2。相反:
- def g(): Int = try { 1 } finally { 2 }
调用g()产生1。这两个例子展示了有可能另大多数程序员感到惊奇的行为,因此通常最好还是避免从finally子句中返回值。最好是把finally子句当作确保某些副作用,如关闭打开的文件,发生的途径。
本文转自http://developer.51cto.com/art/200907/138280.htm,所有权利归原作者所有。
学习Scala:使用try-catch表达式处理异常相关推荐
- selenium 学习、工作 记录,附常见异常和工具方法
selenium 学习.工作 记录,附常见异常和工具方法 基础配置 2020.03.31 开发者模式 设置有认证的http代理 让selenium接管人为打开的chrome 2020.07.23(79 ...
- Scala匿名函数Lambda表达式详解
1 前言 大家好,我是楚生辉,在未来的日子里我们一起来学习大数据相关的技术,一起努力奋斗,遇见更好的自己! 本文详细的介绍了scala的匿名函数,有需要的小伙伴可以学习~ Scala 中定义匿名函数的 ...
- el表达式 java_java基础学习:JavaWeb之EL表达式
其他更多java基础文章: java基础学习(目录) 一.EL表达式 EL 全名为Expression Language.JSP中可以使用EL表达式,EL表达式是用"${}"括起来 ...
- Windows异常学习笔记(五)—— 未处理异常
Windows异常学习笔记(五)-- 未处理异常 要点回顾 最后一道防线 实验一:理解最后一道防线 实验二:新线程的最后一道防线 总结 UnhandledExceptionFilter 实验三:理解U ...
- python 内存溢出能捕获吗_从0基础学习Python (19)[面向对象开发过程中的异常(捕获异常~相关)]...
从0基础学习Python (Day19) 面向对象开发过程中的=>异常 什么是异常 当程序在运行过程中出现的一些错误,或者语法逻辑出现问题,解释器此时无法继续正常执行了,反而出现了一些错误的 ...
- 学习Scala: 初学者应该了解的知识
Scala开发参照清单 这里列出在开发一个Scala工程中需要参照的资料. 官网网站 http://www.scala-lang.org/ 文档网站 http://docs.scala-lang.or ...
- oracle:oracle学习笔记(四)循环、光标、异常、瀑布模型
oracle学习笔记:循环.光标.异常 文章目录 打印Hello World 定义基本变量 引用型变量(单行)` my_name emp.ename%type ` 记录型变量(多行) `emp_rec ...
- C语言学习笔记—code:blocks工具debug调试异常
C语言学习笔记-code:blocks工具debug调试异常 参考文章: (1)C语言学习笔记-code:blocks工具debug调试异常 (2)https://www.cnblogs.com/do ...
- 如何在Scala中使用条件表达式 .
条件表达式 Scala的if/else语法结构和Java或C++一样.不过,在Scala中if/else表达式有值,这个值就是跟在if或else之后的表达式的值.例如: if (x > 0) 1 ...
最新文章
- java课设推荐,《Java程序设计》课程设计报告推荐.docx
- 深度学习发展下的“摩尔困境”,人工智能又将如何破局?
- flutter 图片转base64_京东技术中台的Flutter实践之路
- IntelliJ IDEA创建spring boot项目的方法
- cppcheck的安装和使用
- DriverManager 连接不同的连接池
- esp8266 at接收数据中断时间_关于嵌入式系统中断优先级的一点思考
- input checkbox 选中问题
- unity 反编译 step1 disUnity
- 【随笔】移动端input type|语义与IOS按键
- 笔记本电脑热点手机无法连接解决方案
- bugly android升级,android 新版本升级示例源码(bugly)
- 拔丝芋头的Java学习日记--Day3
- Linux上几款好用的字幕编辑器
- linux使用tmux后台运行程序
- 自媒体视频搬运,技术分享给大家!
- np.arange函数的使用
- 2021江苏省南通市高考成绩查询时间,2021南通市安全教育平台登录入口网址【最新】...
- 整数转罗马数字(C++)
- 51单片机实验——LED灯(点亮、闪烁、流水)
热门文章
- swift笔记1-点语法
- 关于SSH的分工(网友讨论集合贴)
- C语言课后习题(54)
- 数据库-MySQL-结果集-ASORDER BY
- linux中显示进程,linux中怎么显示所有进程
- python导入类属性不存在_为什么我会得到一个错误:我的类中不存在该属性?
- 量化信噪比 非均匀量化_键摄基础1:为什么要正确曝光/ADC精度和量化噪声
- 资源放送丨数据安全:Oracle多场景下比特币勒索的揭密与恢复实战
- Oracle 19c: RAC 集群技术的坚持与放弃(含PPT下载)
- SQL Server 2008处理隐式数据类型转换在执行计划中的增强