第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

Ruby異常捕獲

當(dāng)Ruby的代碼運(yùn)行異常時(shí),會(huì)拋出異常,我們?cè)陂_(kāi)發(fā)時(shí)隨時(shí)可能會(huì)發(fā)生異常,本章節(jié)中讓我們來(lái)了解Ruby中的異常。

1. 什么是異常

在 Ruby 中異常是一種特殊的對(duì)象,它是 Exception 實(shí)例或這個(gè)類的子類。下面引用《Programming Ruby》書中的一個(gè)圖片。

圖片描述

默認(rèn)情況下,當(dāng)程序發(fā)生異常,Ruby程序會(huì)立即終止。不過(guò)我們可以使用異常處理機(jī)制來(lái)處理程序中遇到的異常,它是一個(gè)代碼塊,當(dāng)異常發(fā)生時(shí),將執(zhí)行異常處理的代碼。

2. raise拋出異常

除了編程異常出現(xiàn)的異常外,我們可以使用raise來(lái)強(qiáng)制拋出一個(gè)異常。

實(shí)例:

def raise_exception
  puts "before raise exception"
  raise "This is a exception"
  puts "after raise exception"
end
raise_exception

# ---- 輸出結(jié)果 ----
before raise exception
Traceback (most recent call last):
	1: from test.rb:7:in `<main>'
test.rb:3:in `raise_exception': This is a exception (RuntimeError)

解釋:由打印我們可以看到,當(dāng)執(zhí)行完"before raise exception"的文字輸出后,程序拋出了一個(gè)異常,這個(gè)異常的名稱是我們定義的“This is a exception”。

Tips:默認(rèn)情況下,raise創(chuàng)建RuntimeError類的異常。

我們也可以通過(guò)傳入異常的類型,來(lái)改變r(jià)aise異常的類型。

實(shí)例:

def inverse(x)  
  raise ArgumentError, 'Argument is not numeric' unless x.is_a? Numeric  
  1.0 / x  
end  
puts inverse(2)  
puts inverse('not a number')  

# ---- 輸出結(jié)果 ----
0.5
Traceback (most recent call last):
	1: from test.rb:6:in `<main>'
test.rb:2:in `inverse': Argument is not numeric (ArgumentError)

解釋: 我們?cè)?code>raise后面增加了需要拋出的異常類型,由輸出結(jié)果我們可以看到,最后拋出的異常類型為ArgumentError。

3. 異常處理

為了捕獲異常處理,我們使用begin-end將可能發(fā)生異常的代碼封裝它之中,并使用rescue告訴我們要處理異常的類型。

讓我們捕獲一下第一個(gè)例子的異常。

實(shí)例:

def raise_exception
  puts "before raise exception"
  raise "This is a exception"
  puts "after raise exception"
end

begin
  raise_exception
rescue Security => e
  puts "get the exception"
end

# ---- 輸出結(jié)果 ----
before raise exception
get the exception

解釋:由上面例子我們可以看到,當(dāng)出現(xiàn)異常時(shí),將立刻執(zhí)行rescue后面的語(yǔ)句,而異常中斷后面的代碼不會(huì)執(zhí)行。

Tips:如圖顯示大多數(shù)異常屬于 StandardError,默認(rèn)情況下,Ruby 的異常捕獲只捕獲StandardError 的異常。

我們也可以將異常對(duì)象映射到rescue的后面來(lái)只獲取指定類型的異常。

實(shí)例:

def raise_exception
  puts "before raise exception"
  raise "This is a exception"
  puts "after raise exception"
end

begin
  raise_exception
rescue SecurityError => e
  puts "get the exception"
end

# ---- 輸出結(jié)果 ----
before raise exception
Traceback (most recent call last):
	1: from test.rb:8:in `<main>'
test.rb:3:in `raise_exception': This is a exception (RuntimeError)

解釋:由于異常的類型是 StandardError,所以并不會(huì)觸發(fā)異常捕獲。

我們也可以對(duì)多種異常類型進(jìn)行捕獲。它的形式如下顯示,當(dāng)異常類型不匹配時(shí),會(huì)依次向下進(jìn)行匹配,如果不發(fā)生異常,將執(zhí)行else下面的語(yǔ)句。

begin  
  # -  
rescue OneTypeOfException  
  # -  
rescue AnotherTypeOfException  
  # -  
else  
  # No exceptions  
end  

實(shí)例:

def raise_exception
  puts "before raise exception"
  raise "This is a exception"
  puts "after raise exception"
end

begin
  raise_exception
rescue SecurityError => e
  puts "get the SecurityError"
rescue StandardError => e
  puts "get the StandardError"
end

# ---- 輸出結(jié)果 ----
before raise exception
get the StandardError

解釋:當(dāng)拋出異常后,首先將異常類型和 SecurityError 進(jìn)行對(duì)比,發(fā)現(xiàn)不符合繼續(xù)查找下一個(gè),第二個(gè)異常類型 StandardError 和當(dāng)前異常相符合,于是執(zhí)行了它下面的語(yǔ)句。

4. retry

在捕獲到異常并執(zhí)行rescue下的語(yǔ)句時(shí),我們還可以使用retry來(lái)重新執(zhí)行發(fā)生異常的代碼。

num = 0

begin
  puts "current num = #{num}"
  raise if num < 3
  puts "finished!"
rescue 
  num += 1
  puts 'retry!'
  retry
end

# ---- 輸出結(jié)果 ----
current num = 0
retry!
current num = 1
retry!
current num = 2
retry!
current num = 3
finished!

解釋:當(dāng)num小于 3 時(shí)代碼運(yùn)行會(huì)一直觸發(fā)異常,每次當(dāng)異常發(fā)生時(shí),執(zhí)行num的累加操作并執(zhí)行retry,直到 num 等于 3 不拋出異常代碼結(jié)束。

5. 小結(jié)

本章節(jié)我們學(xué)習(xí)了什么是異常,使用raise強(qiáng)制拋出異常,使用begin-end+rescue來(lái)捕獲異常,以及使用retry重新運(yùn)行出現(xiàn)異常的代碼。