快速查询:Java 程序员将如何理解以下 Ruby 语句:
rescue ErrorType1, ErrorType2 => ex
也就是说,我想明确地在它周围加上括号/括号。那么,是吗?
rescue(ErrorType1, {ErrorType2 => ex})
或者,
rescue({[ErrorType1, ErrorType2] => ex})
或者是其他东西...
快速查询:Java 程序员将如何理解以下 Ruby 语句:
rescue ErrorType1, ErrorType2 => ex
也就是说,我想明确地在它周围加上括号/括号。那么,是吗?
rescue(ErrorType1, {ErrorType2 => ex})
或者,
rescue({[ErrorType1, ErrorType2] => ex})
或者是其他东西...
关于语法:
rescue ErrorType1, ErrorType2 => ex
请注意以下事项:
现在,再次查看语法...
rescue
是具有自己语法的控制结构,它不是方法调用,因此您的第二个和第三个代码块是无效的语法,您没有传递任何参数。
rescue <exception-class1>[, <exception-class2>] => <a variable to assign the exception to>
因此,在执行此操作时rescue TypeError, StandardError => my_exception
,它将捕获引发的任何TypeError
异常StandardError
并将其分配给my_exception
局部变量。
我推荐最近翻译的Ruby Hacking Guide(搜索“rescue”)。
看下面的代码:
begin
a=1/0
rescue => e
p e.class
p defined?(e)
end
# >> ZeroDivisionError
# >> "local-variable"
Wheree
是该异常处理块的局部变量。在 Ruby 中,局部变量是使用赋值操作创建的,但在异常处理的情况下,对当前引发的异常的引用使用哈希 Rocket( =>
) 分配给局部变量 e,而不是=
. 这是按照设计。不要认为它是一个Hash。
在 Ruby 中,我们使用一个或多个救援子句来告诉 Ruby 我们要处理的异常类型。如果您编写一个没有参数列表的救援子句,则参数默认为StandardError
. 每个救援子句可以指定要捕获的多个异常。在每个救援子句的末尾,您可以为 Ruby 提供一个局部变量的名称以接收匹配的异常。救援子句的参数也可以是返回异常类的任意表达式(包括方法调用)。如果我们使用不带参数的 raise,它会重新引发异常。处理异常
在您的三个代码中,只有rescue ErrorType1, ErrorType2 => ex
. 其他人会给你语法错误。
层次结构(部分):
StandardError
|
IndexError
|
KeyError
您可以按任何顺序将错误类名称指定为rescue
列表的参数。在运行时 ruby 将从列表中选择正确的类。看下面的代码:
begin
a = {}
a.fetch(:b)
rescue StandardError,KeyError,IndexError => e
p e.class
end
# >> KeyError
begin
a = {}
a.fetch(:b)
rescue KeyError,StandardError,IndexError => e
p e.class
end
# >> KeyError
如果你认为,你会在运行时告诉 Ruby 解释器,首先使用参数列表中的括号匹配哪个,Ruby不允许你这样做,作为回报,它会向你抛出语法错误。下面也一样:
begin
a = {}
a.fetch(:b)
rescue StandardError => e1
p e1.class
rescue IndexError => e2
p e2.class
rescue KeyError => e3
p e3.class
end
# >> KeyError
注意:如果我们想捕获更多的异常类,我们可以将它们写成一行。当我们想以不同的方式处理不同的错误时,我们可以指定几个rescue
子句。红宝石黑客指南