Scala try 表達式處理異常

2018-09-28 18:23 更新

try 表達式處理異常

Scala 的異常處理和其它語言比如 Java 類似,一個方法可以通過拋出異常的方法而不返回值的方式終止相關代碼的運行。調用函數可以捕獲這個異常作出相應的處理或者直接退出,在這種情況下,異常會傳遞給調用函數的調用者,依次向上傳遞,直到有方法處理這個異常。

拋出異常

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 為偶數時,n 初始化為 n 的一半,而如果 n 為奇數,將在初始化 half 之前就拋出異常,正因為如此,可以把 throw 的返回值的類型為任意類型。技術上來說,拋出異常的類型為 Nothing。對于說明的例子來說整個 if 表達式的類型為可以計算出值的那個分支的類型,如果 n 為 Int,那么 if 表示式的類型也是 Int 類型,而不需要考慮 throw 表達式的類型。

捕獲異常

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 表達式的基本用法和 Java 一樣,如果 try 塊中代碼在執(zhí)行過程中出現異常,將逐個檢測每個 catch 塊,在上面的例子,如果打開文件出現異常,將先檢查是否是 FileNotFoundException 異常,如果不是,再檢查是否是 IOException,如果還不是,在終止 try-catch 塊的運行,而向上傳遞這個異常。

注意:和 Java 異常處理不同的一點是,Scala 不需要你捕獲 checked 的異常,這點和 C# 一樣,也不需要使用 throw 來聲明某個異常,當然如果有需要還是可以通過 @throw 來聲明一個異常,但這不是必須的。

finally語句

Scala 也支持 finally 語句,你可以在 finally 塊中添加一些代碼,這些代碼不管 try 塊是否拋出異常,都會執(zhí)行。比如,你可以在 finally 塊中添加代碼保證關閉已經打開的文件,而不管前面代碼中是否出現異常。

import java.io.FileReader
val file = new FileReader("input.txt")
try {
  //use the file
} finally {
  file.close()
}

生成返回值

和大部分Scala 控制結構一樣,Scala 的 try-catch-finally 也生成某個值,比如下面的例子嘗試分析一個 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 塊用來做些清理工作,而不應該產生結果,但如果在 finally 塊中使用 return 來返回某個值,這個值將覆蓋 try-catch 產生的結果,比如:

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

結果卻是 1,上面兩種情況常常使得程序員產生困惑,因此關鍵的一點是避免在 finally 生成返回值,而只用來做些清理工作,比如關閉文件。

以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號