W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
Scala 的異常處理和其它語言比如 Java 類似,一個(gè)方法可以通過拋出異常的方法而不返回值的方式終止相關(guān)代碼的運(yùn)行。調(diào)用函數(shù)可以捕獲這個(gè)異常作出相應(yīng)的處理或者直接退出,在這種情況下,異常會(huì)傳遞給調(diào)用函數(shù)的調(diào)用者,依次向上傳遞,直到有方法處理這個(gè)異常。
Scala 拋出異常的方法和 Java一樣,使用 throw 方法,例如,拋出一個(gè)新的參數(shù)異常:
throw new IllegalArgumentException
盡管看起來似乎有些自相矛盾,Scala 中,throw 也是一個(gè)表達(dá)式,也是有返回值的,比如下面的例子:
val half =
if (n % 2 == 0)
n/2
else
throw new RuntimeException("n must be even")
當(dāng) n 為偶數(shù)時(shí),n 初始化為 n 的一半,而如果 n 為奇數(shù),將在初始化 half 之前就拋出異常,正因?yàn)槿绱?,可以?throw 的返回值的類型為任意類型。技術(shù)上來說,拋出異常的類型為 Nothing。對(duì)于說明的例子來說整個(gè) if 表達(dá)式的類型為可以計(jì)算出值的那個(gè)分支的類型,如果 n 為 Int,那么 if 表示式的類型也是 Int 類型,而不需要考慮 throw 表達(dá)式的類型。
Scala 捕獲異常的方法和后面介紹的“模式匹配”的使用方法是一致的。比如:
import java.io.FileReader
import java.io.FileNotFoundException
import java.io.IOException
try {
val f = new FileReader("input.txt")
} catch {
case ex: FileNotFoundException => //handle missing file
case ex: IOException => //handle other I/O error
}
模式匹配將在后面介紹,try-catch 表達(dá)式的基本用法和 Java 一樣,如果 try 塊中代碼在執(zhí)行過程中出現(xiàn)異常,將逐個(gè)檢測(cè)每個(gè) catch 塊,在上面的例子,如果打開文件出現(xiàn)異常,將先檢查是否是 FileNotFoundException 異常,如果不是,再檢查是否是 IOException,如果還不是,在終止 try-catch 塊的運(yùn)行,而向上傳遞這個(gè)異常。
注意
:和 Java 異常處理不同的一點(diǎn)是,Scala 不需要你捕獲 checked 的異常,這點(diǎn)和 C# 一樣,也不需要使用 throw 來聲明某個(gè)異常,當(dāng)然如果有需要還是可以通過 @throw 來聲明一個(gè)異常,但這不是必須的。
Scala 也支持 finally 語句,你可以在 finally 塊中添加一些代碼,這些代碼不管 try 塊是否拋出異常,都會(huì)執(zhí)行。比如,你可以在 finally 塊中添加代碼保證關(guān)閉已經(jīng)打開的文件,而不管前面代碼中是否出現(xiàn)異常。
import java.io.FileReader
val file = new FileReader("input.txt")
try {
//use the file
} finally {
file.close()
}
和大部分Scala 控制結(jié)構(gòu)一樣,Scala 的 try-catch-finally 也生成某個(gè)值,比如下面的例子嘗試分析一個(gè) URL,如果輸入的 URL 無效,則使用缺省的 URL 鏈接地址:
import java.net.URL
import java.net.MalformedURLException
def urlFor(path:String) =
try {
new URL(path)
} catch {
case e: MalformedURLException =>
new URL("http://www.scala-lang.org")
}
通常情況下,finally 塊用來做些清理工作,而不應(yīng)該產(chǎn)生結(jié)果,但如果在 finally 塊中使用 return 來返回某個(gè)值,這個(gè)值將覆蓋 try-catch 產(chǎn)生的結(jié)果,比如:
scala> def f(): Int = try { return 1 } finally { return 2}
f: ()Int
scala> f
res0: Int = 2
而下面的代碼:
scala> def g() :Int = try 1 finally 2
g: ()Int
scala> g
res0: Int = 1
結(jié)果卻是 1,上面兩種情況常常使得程序員產(chǎn)生困惑,因此關(guān)鍵的一點(diǎn)是避免在 finally 生成返回值,而只用來做些清理工作,比如關(guān)閉文件。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: