异常处理指的是预测和定义处理程序执行过程中出现的错误的方法。在大多数情况下,错误是指在程序执行过程中出现的意外事件或发生的情况。例如,在读取文件时可能会发生错误,原因是文件不存在或用户没有读取或写入文件的正确权限。
本教程将向你展示如何在Ruby中使用提高和救援块来实现异常处理。
基本用法
大多数编程语言使用try和catch块来实现异常处理。然而,就像Ruby中的其他东西一样,关键字的描述性更强。
我们可以把一般的语法表达出来,如下所示。
begin
raiseexception
# raise ecxeption
rescue exception
# rescue block
end
我们用begin和end语句来包围异常处理块。在这些语句中,我们定义了 raise 和 rescue 块。
在 raise 中,我们定义了异常,我们可以手动提出,也可以让 Ruby 解释器生成。默认情况下,提高块的参数是 RuntimeError
接下来是救援块。顾名思义,当异常发生时,这个块会来救援。它负责控制程序的执行。
Ruby 将比较从 raise 块引发的异常和传递给救援块的参数。如果异常的类型相同或属于超类,它将触发救援块。
Ruby中异常处理的例子
我们可以实现一个简单的例子来说明Ruby中的异常处理是如何工作的。
def err_me
begin
puts "Hi there!"
raise "string type"
rescue
puts "Never mind, I am fixed!"
end
end
err_me
在上面的例子中,我们定义了一个带有异常块的函数。
我们手动引发了一个异常,中断了程序的执行流程并进入救援块。这样就执行了块中的动作--在本例中是一个put语句并退出。
如果你在 raise 之后和救援块之前添加任何代码块,它们都不会执行,因为救援块会立即处理程序流。
默认情况下,救援块使用 StandardError 参数。然而,在Ruby中还有其他类型的错误,包括。
- 语法错误(SyntaxError
- IOError
- RegexpError
- 线程错误
- 零除法错误
- 没有方法的错误
- 索引错误
- 名称错误
- 类型错误
还有更多。
为了提高和处理一个特定的错误类型,我们可以把它作为一个参数传递给提高块。下面是一个例子。
begin
raiseZeroDivisionError
rescue =>exception
puts exception.message
puts exception.backtrace.inspect
end
在上面的例子中,我们提出了一个ZeroDivisionError。然后我们跳转到救援块,它打印出特定的异常类型并追踪其来源。
结果输出为
$ ruby err-handling.rb
ZeroDivisionError
["err-handling.rb:2:in `<main>'"]
其他异常块
除了主要的 raise 和 rescue 块,Ruby 还为我们提供了其他可以实现的块来处理错误。
它们包括。
重试块
重试块是用来在引发异常后重新运行救援块的。下面是一个例子。
begin
raise ZeroDivisionError
puts "I don't run 😢"
rescue => exception
puts "#{exception.message} caused me to die ⚰️"
retry
end
如果我们运行上面的代码,它将打印救援块内的信息。它将遇到重试块,重试块会跳到救援块中。

重试块的一个常见用例是使用蛮力探测错误。一个例子是在连接中断时不断重载一个页面,直到错误解决。
注意: 使用重试块时要小心,因为它是无限循环的一个常见来源。
确保块
如果你用其他语言(如Python)编程,你可能对Final块很熟悉。Ruby中的确保块与其他编程语言中的最后块的性能相似。
ensure块总是在代码的最后运行。无论提出的异常是否被正确处理或程序执行是否终止,它总是运行或执行。
下面是一个例子。
begin
raise ZeroDivisionError
puts "I don't run 😢"
rescue => exception
puts "#{exception.message} caused me to die ⚰️"
ensure
puts "I will always run 🚀"
end
在这种情况下,上面的代码将打印一个异常消息,最后运行确保块。
ZeroDivisionError caused me to die ⚰️
I will always run 🚀
Else块
如果没有产生异常,我们可以使用else语句实现一个块来做一个动作。
比如说
begin
rescue => exception
puts "#{exception.message} caused me to die ⚰️"
else
puts "Trust me, I ran successfully 😀"
ensure
puts "& I will always run 🚀"
end
else块被放在救援和确保块之间。在上面的例子中,你会注意到它缺少一个 raise 块,它导致 else 块的运行。
下面是一个输出示例。
相信我,我运行成功了
& I will always run 🚀
轻量级异常处理
raise和save块是一种方便的方法,当错误发生时可以执行一个动作。然而,由于错误处理会建立一个堆栈跟踪来帮助调试,它很容易在你的程序中成为问题。这就是catch和throw块的用处。
要实现catch-throw块,你首先要用catch关键字定义标签。一旦ruby遇到引用catch块的throw块,它就会停止执行并跳转到catch块。
让我们用一个例子来说明这个概念。考虑一下下面代码中所示的混乱嵌套。
catch(:kill_me_now) do
langs = ["Python", "Ruby", "C++", "C#"]
foriinlangsdo
for index in 1..5
if index == 3
ifi == "C#"
puts "After throw, nothing will run!'"
throw(:kill_me_now)
puts "I am C#"
end
end
end
end
end
puts "Oh boy! That was a long one!"
我们首先使用catch关键字,并在一对括号内传递标签。一旦我们运行代码,它将执行所有的嵌套循环和if语句,直到它遇到引用catch的throw语句。
这将立即终止执行并退出到catch语句的层次。
下面是一个输出的例子。
After throw, nothing will run!'
Oh boy! That was a long one!
总结
本教程向你展示了如何使用 raise 和 rescue 块在 Ruby 中实现错误处理。