【问题标题】:What is the difference when using ensure and else after rescue?救援后使用 ensure 和 else 有什么区别?
【发布时间】:2013-08-02 06:10:13
【问题描述】:
  1. 使用ensure有什么区别:

    begin
      foo_process
    rescue
      bar_process
    ensure
      baz_process
    end
    

    并将进程放在begin ... rescue ... end 块之后?

    begin
      foo_process
    rescue
      bar_process
    end
    baz_process
    
  2. 使用else有什么区别:

    begin
      foo_process
    rescue
      bar_process
    else
      baz_process
    end
    

    并在rescue 之前继续该过程(假设baz_process 不会引发错误)?

    begin
      foo_process
      baz_process
    rescue
      bar_process
    end
    

【问题讨论】:

    标签: ruby rescue


    【解决方案1】:

    1.

    使用ensurebaz_process 始终执行,即使foo_process 抛出异常,从方法返回。

    例如,

    def foo_process
      puts 'foo_process'
      return 111
    end
    
    def f1
      begin
        return foo_process
      rescue 
        puts 'bar_process'
      ensure 
        puts 'baz_process'
      end
    end
    
    def f2
      begin
        return foo_process
      rescue 
        puts 'bar_process'
      end
      puts 'baz_process'
    end
    
    >> f1
    foo_process
    baz_process
    => 111
    >> f2
    foo_process
    => 111
    

    【讨论】:

    • 执行顺序不清楚。 ensure 块是否在执行 return 之前插入?
    • @sawa,为了清楚起见,我修改了代码。 ensure 块在返回调用者之前执行。
    【解决方案2】:

    对于问题 1,使用 ensurebaz_process 将始终运行,即使 rescue 块没有捕获到异常(即在您的示例代码中,即使异常不是 StandardError )。如果bar_process 引发异常,它也会运行。对于放在 begin...rescue...ensure 块之后的代码,这些都不成立。

    对于问题2,不同的是else块中的代码抛出的异常没有被抢救。当还有一个确保块时,这更相关,因为代码将在它之前运行。

    【讨论】:

    • @sawa: 是的,抱歉我错过了这个假设,但是提出这个要求有点令人困惑(有点像在假设 x 总是大于的情况下为什么使用分支条件 if x > y y)。我可以断言没有任何代码会引发错误,在这种情况下,所有变体都是等价的。在begin...rescue...ensure 序列中使用else 时的部分区别是您希望控制哪些代码部分有错误管理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 2021-11-28
    • 2020-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多