'=>'的Ruby语法(hashrocket)

yyhrrdl8  于 2023-08-04  发布在  Ruby
关注(0)|答案(1)|浏览(117)

我尝试了这个earlier,每个人都对救援块语法感到满意。请不要去那里。给出以下工作代码:

begin
  (1..1000).each do |i|
    puts i
    sleep 1
  end
rescue Exception => e
   puts "\nCaught exception..."
   puts "Exception class: #{e.class}"
end

字符串
在运行时按CTRL+C会打印出“Caught exception...”,正如预期的那样。在rescue行中到底发生了什么语法方面,特别是在Exception和变量e之间以及=>之间?
“营救”这个词是一个关键词。。Ruby语言的一部分。“e”是变量,并且可以在功能上是“a”、“b”或“c”。下面的代码也同样有效。

begin
  (1..1000).each do |i|
    puts i
    sleep 1
  end
rescue Exception => b
   puts "\nCaught exception..."
   puts "Exception class: #{b.class}"
end


什么是“Exception”和“=>"?有没有其他的方法来写这个表达式,使它从语法的Angular 更容易理解?我不认为我们在这里处理的是散列,因为下面的代码编译,但只要按下CTRL+C就会抛出错误(未定义的局部变量或方法'e')。

begin
  (1..1000).each do |i|
    puts i
    sleep 1
  end
rescue { Exception => b }
   puts "\nCaught exception..."
   puts "Exception class: #{b.class}"
end


有人能解释一下这是怎么回事吗?以及具体地,在这个具体示例中,什么语言元素‘=>’(hashrocket)是,因为它似乎与散列无关?

pnwntuvh

pnwntuvh1#

我很遗憾地告诉你,这只是一次性的语法,与其他Ruby语法没有任何关系。
给定表达式:

begin
  # ...
rescue FooError, BarError => ex
  # ...
end

字符串

***FooError, BarError**是将被拯救的异常类(通常是StandardError的子类)的列表。它的行为就像一个参数列表,所以你可以(如果你愿意)做这样的事情:

my_exception_classes = [ FooError, BarError ]

begin
  # ...
rescue *my_exception_classes => ex
  # ...
 end


值得注意的是,一般情况下,你不应该在这里使用Exception,因为它会拯救 * 所有 * 异常,包括像SignalException::InterruptNoMemoryError这样的usually isn't what you want

***=>**只是语法,可以说不是最佳的语法选择,因为它会导致像您自己这样的问题。
***ex**是异常对象将被放入的局部变量的名称。

深入挖掘

如果您喜欢阅读解析器语法,那么在parse.y中查看Ruby的YACC语法总是很有趣的。它不是特别容易阅读,但我们可以看到rescue表达式的语法,在语法中称为opt_rescue,在这里:

opt_rescue  : k_rescue exc_list exc_var then
              compstmt
              opt_rescue


k_rescue是关键字rescueexc_list是异常类的列表,就像我说的,就像一个参数列表:

exc_list    : arg_value


exc_var是指定放置异常的变量的部分:

exc_var     : tASSOC lhs


在这里,tASSOC当然是我们的朋友hashrocket(=>),而lhs,即“left-hand side”是一个位于赋值表达式左边的表达式(比如变量名)。
compstmt基本上是“任何有效的Ruby代码”,然后还有opt_rescue,因为你可以(可选地)在begindef块中有许多rescues
正如你所看到的,这个语法与Hash唯一的共同点是tASSOC

相关问题