首页 > 服务端语言 > Ruby 入门教程 > 22 Ruby 异常捕获

Ruby异常捕获

当Ruby的代码运行异常时,会抛出异常,我们在开发时随时可能会发生异常,本章节中让我们来了解Ruby中的异常。

1. 什么是异常

在 Ruby 中异常是一种特殊的对象,它是 Exception 实例或这个类的子类。下面引用《 Programming Ruby 》书中的一个图片。

图片描述

默认情况下,当程序发生异常,Ruby程序会立即终止。不过我们可以使用异常处理机制来处理程序中遇到的异常,它是一个代码块,当异常发生时,将执行异常处理的代码。

2. raise抛出异常

除了编程异常出现的异常外,我们可以使用raise来强制抛出一个异常。

实例:

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

# ---- 输出结果 ----
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)

解释 :由打印我们可以看到,当执行完"before raise exception"的文字输出后,程序抛出了一个异常,这个异常的名称是我们定义的“This is a exception”。

Tips :默认情况下,raise创建RuntimeError类的异常。

我们也可以通过传入异常的类型,来改变raise异常的类型。

实例:

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')

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

解释 : 我们在raise后面增加了需要抛出的异常类型,由输出结果我们可以看到,最后抛出的异常类型为ArgumentError。

3. 异常处理

为了捕获异常处理,我们使用begin-end将可能发生异常的代码封装它之中,并使用rescue告诉我们要处理异常的类型。

让我们捕获一下第一个例子的异常。

实例:

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

# ---- 输出结果 ----
before raise exception
get the exception

解释 :由上面例子我们可以看到,当出现异常时,将立刻执行rescue后面的语句,而异常中断后面的代码不会执行。

Tips :如图显示大多数异常属于 StandardError,默认情况下,Ruby 的异常捕获只捕获StandardError 的异常。

我们也可以将异常对象映射到rescue的后面来只获取指定类型的异常。

实例:

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

# ---- 输出结果 ----
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,所以并不会触发异常捕获。

我们也可以对多种异常类型进行捕获。它的形式如下显示,当异常类型不匹配时,会依次向下进行匹配,如果不发生异常,将执行else下面的语句。

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

实例:

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

# ---- 输出结果 ----
before raise exception
get the StandardError

解释 :当抛出异常后,首先将异常类型和 SecurityError 进行对比,发现不符合继续查找下一个,第二个异常类型 StandardError 和当前异常相符合,于是执行了它下面的语句。

4. retry

在捕获到异常并执行rescue下的语句时,我们还可以使用retry来重新执行发生异常的代码。

num = 0

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

# ---- 输出结果 ----
current num = 0
retry!
current num = 1
retry!
current num = 2
retry!
current num = 3
finished!

解释 :当num小于 3 时代码运行会一直触发异常,每次当异常发生时,执行num的累加操作并执行retry,直到 num 等于 3 不抛出异常代码结束。

5. 小结

本章节我们学习了什么是异常,使用raise强制抛出异常,使用begin-end+rescue来捕获异常,以及使用retry重新运行出现异常的代码。

本文来自互联网用户投稿,不拥有所有权,该文观点仅代表作者本人,不代表本站立场。
访问者可将本网站提供的内容或服务用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯本网站及相关权利人的合法权利。
本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站,邮箱:80764001@qq.com,予以删除。
© 2023 PV138 · 站点地图 · 免责声明 · 联系我们 · 问题反馈